我试图将类型的友好名称作为模板类型名称,因为我需要在函数中的几个位置使用该名称。该类型是根据参数包中其他模板参数的数量推断出来的,如下所示:
#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;
}
这个编译很好,但两个断言都失败了,因为别名Functor
实际上不是std::function<>
。另一方面,如果我更改代码以在Functor
调用中重复typeid
的定义,则它可以完美地运行,如下所示:
#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;
}
为什么第一个声明(使用typname Functor = ...
)不正确?是否有不同的方法来制作别名?请注意,在回答第二个问题时,如果解决方案是const表达式,则可以使用constexpr
,但这些示例仅为typeid
。
答案 0 :(得分:1)
为什么第一个声明(使用
typename Functor = ...
)不正确?
您正在为模板参数Functor
提供默认类型。但是,仅在未以其他方式指定或推导出类型时才使用默认类型。在这种情况下,模板推导将在两种情况下推导出Functor
,无论是调用它的lambda的唯一类型(当Args...
推导为空包时)。
这类似于提供它们时未使用的默认函数参数。
我不确定您的assert()
应该完成什么,但如果您要检查类型,则应使用static_assert
。