Reputation: 1012
So, I have this template class and its specialization.
#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
};
Case 1:
In the main
function I am defining a local class called ErrorA
. When I create a temporary of CompileTimeChecker<false>
with temporary object of ErrorA
fed as an initializer, the compiler is not detecting any error.
int main()
{
class ErrorA {};
CompileTimeChecker<false>(ErrorA()); //Case 1;
CompileTimeChecker<false>(int()); //Case 2;
return 0;
}
Case 2:
Next I feed it with temporary object of type int
, and suddenly the compiler recognizes the issue (there is no constructor that takes args in the specialized template CompileTimeChecker<false>
)
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
Why does it not recognize the issue in case 1?
Upvotes: 1
Views: 53
Reputation: 52546
CompileTimeChecker<false>(ErrorA());
does not create a temporary of type CompileTimeChecker<false>
, passing a temporary ErrorA()
to its constructor. Rather, it declares a function named ErrorA
, taking no parameters and returning CompileTimeChecker<false>
. See also: most vexing parse.
On the other hand, CompileTimeChecker<false>(int());
cannot be parsed as a declaration, so it does unambiguously create a temporary of type CompileTimeChecker<false>
.
The easiest way out is to use braces in place of parens to indicate initialization:
CompileTimeChecker<false>{ErrorA{}};
Upvotes: 2