Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alias a templated function

Tags:

You can use a typedef to create a shorter and simpler name for types:

typedef std::chrono::high_resolution_clock Clock;
typedef Clock::time_point TimePoint;
typedef std::chrono::seconds Seconds;
typedef std::chrono::milliseconds Milliseconds;

As well as for instantiated templated types:

typedef std::chrono::duration<float, std::ratio<1>> RealDuration;

// Example usage
float dt = RealDuration(a - b).count();

And for function pointers:

typedef void (*FuncPtr)(int,int);

You can also use type aliases for templates:

template<typename T> using uptr = std::unique_ptr<T>;

// Example usage
uptr<int> myInt;
uptr<foo> myFoo;

But how can you create an alias/pointer to a templated function? For example, if I want to be able to use the name DurationCast to write things like this:

x = DurationCast<Seconds>(a - b);
y = DurationCast<Milliseconds>(c - d);

What needs to be done to shorten the function std::chrono::duration_cast<T>() to just DurationCast<T>() without simply going the using namespace std::chrono; or using std::chrono::duration_cast; route, and without writing my own function objects to achieve it?

EDIT: I guess I can just write a simple wrapper around it:

template<typename ToType, typename FromType>
ToType DurationCast(const FromType& d)
{
    return std::chrono::duration_cast<ToType>(d);
}

Doesn't work like an alias, but the end result is that I can use it in the exact same way I was aiming for:

x = DurationCast<Seconds>(a - b);
like image 780
derpface Avatar asked Oct 03 '14 17:10

derpface


People also ask

What is an alias in C++?

You can use an alias declaration to declare a name to use as a synonym for a previously declared type. (This mechanism is also referred to informally as a type alias). You can also use this mechanism to create an alias template, which can be useful for custom allocators.

What is a templated function C++?

Function templates. Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type. In C++ this can be achieved using template parameters.

What is an alias template?

Alias templates are a way to give a name to a family of types. Template parameters can be types, non-types, and templates themselves.


2 Answers

how can you create an alias/pointer to a templated function?

You can alias a variable of a function pointer type:

template <typename T>
void foo()
{
    std::cout << "foo!" << (T)3.14f << std::endl;
}

template <typename T>
constexpr void(*foo_alias)() = &foo<T>;

int main()
{
   foo_alias<int>();    // 3
   foo_alias<float>();  // 3.14
}

For example, if I want to be able to use the name DurationCast (...) What needs to be done to shorten the function std::chrono::duration_cast<T>() to just DurationCast<T>() ?

The trick with a pointer to function is that you have to specify all types of arguments to get the address of a function, as such, you need all parameters' types explicitly given or templated. Unfortunately, std::chrono::duration_cast takes three parameters:

template <typename T, class Rep, class Period>
constexpr T(*DurationCast)(const std::chrono::duration<Rep, Period>&) = &std::chrono::duration_cast<T, Rep, Period>;

std::chrono::seconds s(1);
std::chrono::milliseconds ms = DurationCast<std::chrono::milliseconds, float, std::ratio<1>>(s);
//                                                                     ~~~~^  ~~~~~~~~~~~~^
//                                                       explicit representation and period

DEMO

like image 161
Piotr Skotnicki Avatar answered Oct 02 '22 06:10

Piotr Skotnicki


You can create a helper function which forwards to duration_cast:

template <typename T, typename U>
auto DurationCast(U const& u) -> decltype(std::chrono::duration_cast<T>(u))
{
    return std::chrono::duration_cast<T>(u);
}
like image 40
user2030677 Avatar answered Oct 02 '22 06:10

user2030677