将命名为lambda用作模板类参数或构造函数参数时,类模板无法编译

dia*_*iaz 5 c++ lambda templates class-template generic-lambda

我目前正在尝试使用类模板编程,并且遇到了这种奇怪的行为,在将命名的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;
};
Run Code Online (Sandbox Code Playgroud)

编译器错误消息:(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);
                ^

Run Code Online (Sandbox Code Playgroud)

请原谅我的格式,并编译错误消息代码段,因为它与确切的行不匹配。我正在使用g ++ 7.4.0,并使用c ++ 17功能进行编译。

R S*_*ahu 4

在 C++ 中,您可以将变量声明为

\n\n
int(i);\n
Run Code Online (Sandbox Code Playgroud)\n\n

这与以下相同

\n\n
int i;\n
Run Code Online (Sandbox Code Playgroud)\n\n

在你的情况下,这些行

\n\n
Test(isEven);\nTest<decltype(isEven)>(isEven);\n
Run Code Online (Sandbox Code Playgroud)\n\n

就像您声明变量一样进行编译isEven。我很惊讶来自编译器的错误消息与我希望看到的如此不同。

\n\n

您也可以使用一个简单的类来重现该问题。

\n\n
class Test{\n   public:\n      Test(int i) : _i(i) {}\n   private:\n      int _i;\n};\n\nint main(){\n\n   int i = 10;\n\n   Test(i);\n   return 0;\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的编译器 g++ 7.4.0 出现错误:

\n\n\n\n
$ g++ -std=c++17 -Wall    socc.cc   -o socc\nsocc.cc: In function \xe2\x80\x98int main()\xe2\x80\x99:\nsocc.cc:15:11: error: conflicting declaration \xe2\x80\x98Test i\xe2\x80\x99\n     Test(i);\n           ^\nsocc.cc:10:9: note: previous declaration as \xe2\x80\x98int i\xe2\x80\x99\n     int i = 10;\n
Run Code Online (Sandbox Code Playgroud)\n