仅定义默认构造函数时,专用模板接受构造函数参数

时间:2019-07-30 02:12:48

标签: c++11

因此,我有这个模板类及其专门知识。

    #include <iostream>

    using namespace std;

    template<bool> struct CompileTimeChecker{

         CompileTimeChecker(...); //constructor, can accept any number of parameters;

    };

    //specialized template definition

    template<> struct CompileTimeChecker<false> {

        //default constructor, body empty

    };

案例1:

main函数中,我定义了一个名为ErrorA的本地类。当我创建临时对象CompileTimeChecker<false>作为初始化程序的临时ErrorA时,编译器未检测到任何错误。

int main()
{

    class ErrorA {};

    CompileTimeChecker<false>(ErrorA()); //Case 1;

    CompileTimeChecker<false>(int());    //Case 2;

    return 0;

}

案例2:

接下来,我将其馈入类型为int的临时对象,突然编译器意识到了这个问题(专用模板CompileTimeChecker<false>中没有使用args的构造函数)

main.cpp:30:36: error: no matching function for call to ‘CompileTimeChecker::CompileTimeChecker(int)’ CompileTimeChecker<false>(int());

main.cpp:21:23: note: candidate: constexpr CompileTimeChecker::CompileTimeChecker()
     template<> struct CompileTimeChecker<false> {
                       ^~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:21:23: note:   candidate expects 0 arguments, 1 provided

为什么在情况1下无法识别该问题?

1 个答案:

答案 0 :(得分:2)

CompileTimeChecker<false>(ErrorA());

不会创建类型CompileTimeChecker<false>的临时变量,而将临时ErrorA()传递给其构造函数。相反,它声明了一个名为ErrorA的函数,不带任何参数并返回CompileTimeChecker<false>。另请参阅:most vexing parse

另一方面,CompileTimeChecker<false>(int());不能被解析为声明,因此它确实可以创建类型为CompileTimeChecker<false>的临时类型。

最简单的方法是使用括号代替括号来指示初始化:

CompileTimeChecker<false>{ErrorA{}};