テンプレート引数の推定が失敗する次のコードを書きました。
template<int>
struct num {};
template<int m>
void match(num<2*m>) {
}
int main()
{
match(num<2>());
return 0;
}
コンパイラが正しいm
. 誰かが解明できますか?
基本的に、 の2 * m == 2
テンプレート引数を決定するためにm
、コンパイラに方程式を解くように求めていますmatch
。コンパイラは、方程式がどれほど単純で明確であっても、テンプレートの引数推定中に方程式を解きません。
14.8.2.4/14 (C++03)、14.8.2.5/16 (C++11) の言語仕様はあなたの状況をカバーしており、同様の例があります
14非型のtemplate-parameterを持つ関数テンプレートの宣言で、 非型のtemplate-parameterが関数の parameter-list の式で使用される場合、対応する template-argumentは常に明示的に指定または推定されなければなりませんそうしないと、そのようなtemplate-argumentに対して型推定が常に失敗するためです。
template<int i> class A { /* ... */ };
template<short s> void g(A<s+1>);
void k() {
A<1> a;
g(a); //error: deduction fails for expression s+1
g<0>(a); //OK
}
なぜそのように行われるのかについては... 一般的に、数式を解く問題が複雑すぎることは明らかだと思います。また、あいまいなソリューションや、予想されるドメインに属さないソリューションにつながる可能性もあります。たとえば、コンパイラは何を推測するとmatch(num<3>())
思いますか?