gcc不接受通过嵌套模板使用子句

时间:2018-01-25 17:05:42

标签: c++ templates gcc c++14

标题似乎令人费解,但我们的测试用例实际上是一个真实案例的最小例子。

我们有代码,我们希望根据模板参数选择方法的实现。我们在清理期间使用using子句定义了条件enable_if_t,并且由于下一步想要将定义置于行之​​外,这产生了以下代码:

#include <type_traits>
#include <iostream>
#include <string>

template <typename T>
struct A {
    template <typename U>
    using is_int_or_float = std::enable_if_t< std::is_same<U, int>::value || std::is_same<U, float>::value >;

    template<typename U = T, is_int_or_float<U>* = nullptr >
    void f();
    template<typename U = T, typename std::enable_if_t< std::is_same<U,std::string>::value >* = nullptr >
    void f();
};

template <typename T>
template <typename U, typename A<T>::template is_int_or_float<U>* >
void  A<T>::f(){
    std::cout << "f for int or float\n";
}

template <typename T>
template<typename U, typename std::enable_if_t< std::is_same<U,std::string>::value >*>
void A<T>::f() {
    std::cout << "f for string\n";
}

int main () {
    A<int> a_int;
    A<std::string> a_string;
    A<float> a_float;
    a_int.f();
    a_string.f();
    a_float.f();
    a_float.f<std::string>();
    return 0;
}

当clang执行时,Gcc不接受它:https://godbolt.org/g/Gfm1tw

gcc(和icc)抱怨使用is_int_or_float定义的方法没有有效的原型。

我不确定clang是否过于混乱,或者gcc应该能够超越依赖类型。

如果我们为其定义切换typename A<T>::template is_int_or_float<U>,则代码有效:

template <typename T>
template <typename U, std::enable_if_t< std::is_same<U, int>::value || std::is_same<U, float>::value >* >
void  A<T>::f(){
    std::cout << "f for int or float\n";
}

使用using是否会更改有关类型匹配的规则,或者gcc是否应该使用它?

编辑:感谢@VTT的输入,我们发现,差异在于外线声明typename中的typename A<T>::template is_int_or_float<U>*关键字。删除它会使gcc compile和clang拒绝代码。

所以问题可以改写和简化:在这种情况下是否需要typename或允许这样做?

0 个答案:

没有答案