问题
Today, a friend of mine and I struggled a lot on a stupid mistake, and I make me wondered about how template parameters work in C++. Consider the following code, where I try to partially specialize a class attr<MyClass<I>>
where I
is an unsigned int
, though MyClass
expects an int
parameter :
#include <iostream>
template<int I>
class MyClass
{
};
template<typename T>
struct attr;
template<unsigned int I>
struct attr<MyClass<I>>
{
};
int main(int argc, char *argv[])
{
attr<MyClass<1>> att;
return 0;
}
g++
fails with error message
main.cpp: In function ‘int main(int, char**)’:
main.cpp:20:22: erreur : aggregate ‘attr<MyClass<1> > att’ has incomplete type and cannot be defined
attr<MyClass<1>> att;
And clang
compiles it (only a warning due to the fact that att
is unused).
So I was wondering :
is there anything in the spec that would rule in favor of one or the other ?
could we say that
clang
template parameter's typing is weaker thang++
's ?
回答1:
Yes, GCC is correct to reject, at least according to current Standards. Perhaps Clang folks implement some defect report here, I wouldn't know.
http://eel.is/c++draft/temp.deduct.type#17
If P has a form that contains
<i>
, and if the type of the corresponding value of A differs from the type of i, deduction fails. If P has a form that contains[i]
, and if the type of i is not an integral type, deduction fails.
Their testcase in their testsuite tests this only for for functions, for which they appear to emit sensible error messages: https://github.com/llvm-mirror/clang/blob/master/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp.
Also, since the partial specialization can never be deduced, we also run into http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#549 , which asks whether such constructs should possibly be rejected up-front. In my opinion, http://eel.is/c++draft/temp.res#8 could be applied if you wanted:
"Knowing which names are type names allows the syntax of every template to be checked. The program is ill-formed, no diagnostic required, if:
- no valid specialization can be generated for a template and that template is not instantiated, or ..."
There is no legal way to trigger an instantiation of that template, hence you could argue that no valid specialization can be generated for it. Under that interpretation, behavior is undefined and anything is legal to do.
来源:https://stackoverflow.com/questions/35920518/c-template-parameter-and-partial-specialization-strong-or-weak-typing