繁体   English   中英

Variadic模板代码在GCC 4.6上编译,但不在clang或GCC 4.7上编译

[英]Variadic template code compiles on GCC 4.6 but not on clang or GCC 4.7

我有这个代码(从更复杂的版本简化):

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);
}

如果我使用g++ -std=c++0x filename.cpp在GCC 4.6.3上编译它,那么在clang 3.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'

现在的问题是:为什么失败或我做错了什么?

作为解决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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM