是否可以通过 lambda 将变量模板传递给函数?
Is it possible to pass variable template to function through lambda?
据我所知 ,我现在正在努力以类似的方式传递变量模板。
这是我尝试过的最小示例:
#define PASS_VARIABLE_TEMPLATE(name) [dummy=nullptr](auto&&...args) \
{return name<decltype(args)...>;}
//testing
template <typename T>
bool value = std::is_fundamental<T>::value;
template <typename Hax>
void print_bool(Hax h)
{
std::cout << h(int{}) << std::endl; // no error, wrong output
//std::cout << h(int{}, float{}) << std::endl; // error, good
}
int main()
{
print_bool(PASS_VARIABLE_TEMPLATE(value)); //prints 0 instead of 1
}
如果编译通过,为什么输出错误?
template<class T>struct tag_t{using type=T; constexpr tag_t(){}};
template<class Tag>using tagged_type=typename Tag::type;
template<class T>constexpr tag_t<T> tag{};
这些有助于将类型作为值传递并解压它们。
#define PASS_VARIABLE_TEMPLATE(name) [](auto...args) \
{return name<tagged_type<decltype(args)>...>;}
在print_bool
里面你做的:
std::cout << h(tag<int>) << std::endl;
不确定你为什么要做 dummy=nullptr
事情。
tag
作为模板可以不受干扰地承载类型。
您的代码的主要问题是 decltype
将参数推断为 rvalue
引用 (int&&
),因为您的 lambda 使用 转发引用 接受参数。
std::is_fundamental
将与 裸 类型配合使用。
对于您的特定代码段,正确的解决方案是 remove the reference。
#define PASS_VARIABLE_TEMPLATE(name) \
[dummy=nullptr](auto&&...args){return name<std::remove_reference_t<decltype(args)>...>;}
现在可以了。 :-) 看到它 Live On Coliru
稍微多一点或更好的通用方法是另外 remove cv qualifiers. In the end, you may want to use std::decay
#define PASS_VARIABLE_TEMPLATE(name) [dummy=nullptr](auto&&...args) \
{return name<std::decay_t<decltype(args)>...>;}
据我所知
这是我尝试过的最小示例:
#define PASS_VARIABLE_TEMPLATE(name) [dummy=nullptr](auto&&...args) \
{return name<decltype(args)...>;}
//testing
template <typename T>
bool value = std::is_fundamental<T>::value;
template <typename Hax>
void print_bool(Hax h)
{
std::cout << h(int{}) << std::endl; // no error, wrong output
//std::cout << h(int{}, float{}) << std::endl; // error, good
}
int main()
{
print_bool(PASS_VARIABLE_TEMPLATE(value)); //prints 0 instead of 1
}
如果编译通过,为什么输出错误?
template<class T>struct tag_t{using type=T; constexpr tag_t(){}};
template<class Tag>using tagged_type=typename Tag::type;
template<class T>constexpr tag_t<T> tag{};
这些有助于将类型作为值传递并解压它们。
#define PASS_VARIABLE_TEMPLATE(name) [](auto...args) \
{return name<tagged_type<decltype(args)>...>;}
在print_bool
里面你做的:
std::cout << h(tag<int>) << std::endl;
不确定你为什么要做 dummy=nullptr
事情。
tag
作为模板可以不受干扰地承载类型。
您的代码的主要问题是 decltype
将参数推断为 rvalue
引用 (int&&
),因为您的 lambda 使用 转发引用 接受参数。
std::is_fundamental
将与 裸 类型配合使用。
对于您的特定代码段,正确的解决方案是 remove the reference。
#define PASS_VARIABLE_TEMPLATE(name) \
[dummy=nullptr](auto&&...args){return name<std::remove_reference_t<decltype(args)>...>;}
现在可以了。 :-) 看到它 Live On Coliru
稍微多一点或更好的通用方法是另外 remove cv qualifiers. In the end, you may want to use std::decay
#define PASS_VARIABLE_TEMPLATE(name) [dummy=nullptr](auto&&...args) \
{return name<std::decay_t<decltype(args)>...>;}