我目前正在尝试类模板编程,遇到了一个奇怪的行为,当将命名的lambda作为参数传递时我无法理解。有人可以解释为什么下面的(1)和(2)不起作用吗?
template<typename Predicate>
class Test{
public:
Test(Predicate p) : _pred(p) {}
private:
Predicate _pred;
};
int main(){
auto isEven = [](const auto& x){ return x%2 == 0; };
// Working cases
Test([](const auto& x){ return x%2 == 0; });
Test{isEven};
auto testObject = Test(isEven);
// Compilation Error cases
Test(isEven); // (1) Why??? Most vexing parse? not assigned to a variable? I cant understand why this fails to compile.
Test<decltype(isEven)>(isEven); // (2) Basically same as (1) but with a workaround. I'm using c++17 features, so I expect automatic class parameter type deduction via its arguments
return 0;
};
编译器错误消息:与(1)和(2)相同
cpp/test_zone/main.cpp: In function ‘int main()’:
cpp/test_zone/main.cpp:672:16: error: class template argument deduction failed:
Test(isEven);
^
cpp/test_zone/main.cpp:672:16: error: no matching function for call to ‘Test()’
cpp/test_zone/main.cpp:623:5: note: candidate: template<class Predicate> Test(Predicate)-> Test<Predicate>
Test(Predicate p): _p(p){
^~~~
cpp/test_zone/main.cpp:623:5: note: template argument deduction/substitution failed:
cpp/test_zone/main.cpp:672:16: note: candidate expects 1 argument, 0 provided
Test(isEven);
^
请原谅我的格式,并编译错误消息代码段,因为它与确切的行不匹配。我正在使用g ++ 7.4.0,并使用c ++ 17功能进行编译。
答案 0 :(得分:4)
在C ++中,您可以将变量声明为
int(i);
与
相同int i;
在您的情况下,行
Test(isEven);
Test<decltype(isEven)>(isEven);
就像您在声明变量isEven
一样被编译。我很惊讶您的编译器发出的错误消息与我希望看到的消息如此不同。
您也可以通过一个简单的类重现该问题。
class Test{
public:
Test(int i) : _i(i) {}
private:
int _i;
};
int main(){
int i = 10;
Test(i);
return 0;
};
我的编译器g ++ 7.4.0错误:
$ g++ -std=c++17 -Wall socc.cc -o socc
socc.cc: In function ‘int main()’:
socc.cc:15:11: error: conflicting declaration ‘Test i’
Test(i);
^
socc.cc:10:9: note: previous declaration as ‘int i’
int i = 10;
答案 1 :(得分:2)
正如您所说,这是一个最令人头疼的解析问题; # this will open the list box
driver.execute_script("arguments[0].click()",driver.find_element_by_xpath("(//div[@role='option'])[1]"))
# this will select the option
driver.find_element_by_xpath("(//div[@role='listitem']//span[.='Option 4'])[2]").click()
试图重新定义名称为Test(isEven);
且与isEven
相同的变量。
如您所示,可以使用Test<decltype(isEven)>(isEven);
代替{}
,这是自C ++ 11以来最好的解决方案。或者您可以添加其他括号(使其成为函数样式的强制转换)。
()