Reputation: 218
I'm attempting to give a friendly name to a type as a template typename because I need to use the name in a few places within the function. The type is being deduced based on the number of other template arguments in the parameter pack, as shown below:
#include <cassert>
#include <functional>
#include <type_traits>
template < typename ... TArgs, typename Functor = std::function< std::conditional_t< sizeof...(TArgs) == 0, int (), int (TArgs...) > > >
void DoStuff(const Functor & func, TArgs ... args) {
if constexpr (sizeof...(TArgs) == 0)
assert(typeid(Functor).hash_code() == typeid(std::function<int ()>).hash_code());
else
assert(typeid(Functor).hash_code() == typeid(std::function<int (TArgs...)>).hash_code());
}
int main(int argc, char * argv[]) {
DoStuff([] () { return 5; });
DoStuff([] (int a) { return a; });
return 0;
}
This compiles just fine, but both assertions fail because the alias Functor
is not actually a std::function<>
. On the other hand, if I change the code to repeat the definition of Functor
in the typeid
calls it works perfectly, like below:
#include <cassert>
#include <functional>
#include <type_traits>
template < typename ... TArgs, typename Functor = std::function< std::conditional_t< sizeof...(TArgs) == 0, int (), int (TArgs...) > > >
void DoStuff(const Functor & func, TArgs ... args) {
if constexpr (sizeof...(TArgs) == 0)
assert(typeid(std::function< std::conditional_t< sizeof...(TArgs) == 0, int (), int (TArgs...) > >).hash_code() == typeid(std::function<int ()>).hash_code());
else
assert(typeid(std::function< std::conditional_t< sizeof...(TArgs) == 0, int (), int (TArgs...) > >).hash_code() == typeid(std::function<int (TArgs...)>).hash_code());
}
int main(int argc, char * argv[]) {
DoStuff([] () { return 5; });
DoStuff([] (int a) { return a; });
return 0;
}
Why is the first declaration (using the typname Functor = ...
) incorrect? Is there a different way to make that alias? Note that in answering the second question, it is OK if the solution is a const expression, the examples are only not constexpr
because of the use of typeid
.
Upvotes: 0
Views: 134
Reputation: 302892
Why is the first declaration (using the
typename Functor = ...
) incorrect?
You're providing a default type for the template parameter Functor
. But the default type is only used if the type is not otherwise specified or deduced. In this case, template deduction will deduce Functor
in both cases to be whatever the unique type of the lambda is that it is invoked with (while Args...
deduces as an empty pack).
This is similar to default function arguments not being used when they are provided.
I'm not sure what your assert()
s are supposed to accomplish, but if you're checking types you should use static_assert
.
Upvotes: 1