9

私はこのコードを持っています(より複雑なバージョンから簡略化されています):

template <class... A1> class Test {
    public:
    template <class... A2> void print (void(*function)(A2...,A1...)) {

    }
};

void test_print (int a, float b, double c) {

}

int main () {
    Test<float,double> test;
    test.print<int> (&test_print);
}

GCC 4.6.3でコンパイルすると正常にコンパイルされますg++ -std=c++0x filename.cppが、clang3.0でコンパイルclang++ -std=c++0x filename.cppすると次のエラーが発生します。

filename.cpp:14:10: error: no matching member function for call to 'print'
    test.print<int> (&test_print);
    ~~~~~^~~~~~~~~~
filename.cpp:3:33: note: candidate template ignored: failed template argument deduction
    template <class... A2> void print (void(*function)(A2...,A1...)) {
                                ^
1 error generated.

GCC 4.7.2では、次のエラーもあります。

filename.cpp: In function 'int main()':
filename.cpp:14:33: error: no matching function for call to 'Test<float, double>::print(void (*)(int, float, double))'
filename.cpp:14:33: note: candidate is:
filename.cpp:3:33: note: template<class ... A2> void Test::print(void (*)(A2 ..., A1 ...)) [with A2 = {A2 ...}; A1 = {float, double}]
filename.cpp:3:33: note:   template argument deduction/substitution failed:
filename.cpp:14:33: note:   mismatched types 'float' and 'int'

ここで問題は、なぜ失敗するのか、何が間違っているのかということです。

4

1 に答える 1

2

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1399の解決の一環として、演繹不可能なパラメータパックは演繹に参加しないことが決定されたため、パラメータリスト内で明示的に指定された引数。ただし、後続の関数パラメータへの後続の引数の一致を妨げることはありません。ただし、これらの追加されたルールは、型を比較す​​るときに必ずしも控除に適用されるわけではありません(これは、関数呼び出しの引数に対するパラメーターのセットの控除のサブアルゴリズムです)。

私は、決議はあなたの状況にも適用されるべきであり、それを単に仕様が完全に明確ではない領域と見なすべきであると主張します。それぞれのコンパイラにバグレポートを送信し、WG21に問題レポートを送信して、これを明確にするように依頼することができます(ただし、これが標準的な仕様の問題であるとまでは言えませんが、標準では、推論できないコンテキストは控除に参加しないと他の場所で述べています)。

囲んでいるクラステンプレートのパラメータであることに注意してA1ください(したがって、クラスがインスタンス化されると通常のパラメータになります)。テンプレート引数の推論に関する限り、それらを省略して同じ意味を維持できます。

class Test {
    public:
    template <class... A2> void print (A2..., float, double) {

    }
};

int main () {
    Test test;
    test.print<int> (1, 1.0f, 1.0); // works
}
于 2013-02-03T13:35:22.947 に答える