neg*_*tin 5 c++ lambda templates c++14
想象一下,我有这个结构:
struct Foo {
operator int() {
return 11;
}
operator unsigned int() {
return 22;
}
} foo;
Run Code Online (Sandbox Code Playgroud)
当此结构转换为int时,它返回11,但是当转换为unsigned int时,它返回22.
使用普通函数,我可以使用模板和getter函数来选择:
template<typename T>
T get() {
return (T)foo;
}
Run Code Online (Sandbox Code Playgroud)
现在,当调用此函数时,get<int>()它会返回11,但是当它调用它get<unsigned int>()时会返回22.
直到现在,当我尝试使用lambdas时,一切都没问题:
auto lambda=[](auto type) {
return (decltype(type))foo;
};
Run Code Online (Sandbox Code Playgroud)
现在在lambda(0)返回时调用lambda 11,并将其作为lambda(0U)返回值调用22.
这可以正常工作,虽然相当"hacky",但需要使用类型的实例,这对于较大的类型来说并不理想.因此,实现这一点的另一种方式,甚至是"hackier":
auto lambda=[](auto* typePointer) {
return (decltype(*typePointer))foo;
};
Run Code Online (Sandbox Code Playgroud)
现在将其称为lambda((int*)NULL)返回11但将其称为lambda((unsigned int*)NULL)返回22.您可能已经注意到这是相当冗长和"hacky",所以我尝试了一种更简单和传统的方法:
auto lambda=[]<typename T>() {
return (T)foo;
};
Run Code Online (Sandbox Code Playgroud)
起初我认为它不会编译,因为我没有在任何地方看到这种语法,但它确实编译(至少使用GCC).但是,在尝试调用它时,错误会显示出来:
lambda();
testlambda.cpp: In function ‘int main()’:
testlambda.cpp:25:9: error: no match for call to ‘(main()::<lambda()>) ()’
lambda();
^
testlambda.cpp:22:29: note: candidate: template<class T> main()::<lambda()>
auto lambda=[]<typename T>() {
^
testlambda.cpp:22:29: note: template argument deduction/substitution failed:
testlambda.cpp:25:9: note: couldn't deduce template parameter ‘T’
lambda();
^
Run Code Online (Sandbox Code Playgroud)
如你所见,候选人是template<class T> main()::<lambda()>,但这也不编译:
lambda<int>() - > error: expected primary-expression before ‘int’
所以,我的问题是:如果有的话,官方的,符合标准的方式是什么?我真的希望指针黑客不是唯一的方法.在真实代码中使用它似乎非常笨拙.
我正在使用G ++(GCC 5.4.0)作为我的编译器.我也在使用C++ 14标准-std=c++14.
您可以传递空标记类型的变量模板:
template <class T> struct tag_t { using type = T; };
template <class T>
constexpr tag_t<T> tag{};
Run Code Online (Sandbox Code Playgroud)
你可以写你的lambda:
auto lambda = [](auto type) {
return static_cast<typename decltype(type)::type>(foo);
};
Run Code Online (Sandbox Code Playgroud)
要么
auto lambda = [](auto type) -> typename decltype(type)::type {
return foo;
};
Run Code Online (Sandbox Code Playgroud)
并称之为:
lambda(tag<int> ); // 11
lambda(tag<unsigned> ); // 22
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
164 次 |
| 最近记录: |