想象一下我有这个结构:
struct Foo {
operator int() {
return 11;
}
operator unsigned int() {
return 22;
}
} foo;
当此结构体转换为 int 时,它返回 11,但当转换为 unsigned int 时,它返回 22。
使用普通函数,我可以使用模板和 getter 函数来选择:
template<typename T>
T get() {
return (T)foo;
}
现在,当像这样调用这个函数时get<int>()
它会返回11
,但是当这样称呼它时get<unsigned int>()
它会返回22
.
直到现在,当我尝试使用 lambda 时,一切都很好:
auto lambda=[](auto type) {
return (decltype(type))foo;
};
现在当调用 lambda 时lambda(0)
它返回11
,并将其称为lambda(0U)
回报22
.
这可以正常工作,尽管相当“hacky”,但是需要使用该类型的实例,这对于较大的类型来说并不理想。
因此出现了另一种方法,甚至是“更黑客”的方法来实现这一目标:
auto lambda=[](auto* typePointer) {
return (decltype(*typePointer))foo;
};
现在称其为lambda((int*)NULL)
回报11
但称其为lambda((unsigned int*)NULL)
回报22
。
正如您可能已经注意到的那样,这是相当冗长和“hacky”的,所以我尝试了一种更简单和传统的方法:
auto lambda=[]<typename T>() {
return (T)foo;
};
起初我以为它不会编译,因为我在任何地方都没有看到这个语法,但它确实可以编译(至少使用 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();
^
如您所见,候选人是template<class T> main()::<lambda()>
,但这也不能编译:
lambda<int>()
-> error: expected primary-expression before ‘int’
所以,我的问题是:官方的、符合标准的方法是什么(如果有的话)?我真的希望指针破解不是唯一的方法。在实际代码中使用似乎很笨拙。
我使用 G++ (GCC 5.4.0) 作为我的编译器。我也在使用 C++14 标准,例如-std=c++14
.