类模板非依赖成员变量中是否需要模板限定符?

时间:2017-06-29 05:46:01

标签: c++ templates gcc clang

我收到编译错误"错误:使用'模板'要关注的关键词“foo'作为依赖模板名称"当我在注释行上编译以下代码时。 (TEST4)

代码的所有其他部分都已成功编译。

#include <tuple>

struct my {
    template <typename T>
    void foo() {}
};

void test1() {
    my m;
    auto tr = std::forward_as_tuple(m);
    auto& t0 = std::get<0>(tr);
    t0.foo<int>();
}

template <typename T>
struct test2 {
    void method() {
        my m;
        auto tr = std::forward_as_tuple(m);
        auto& t0 = std::get<0>(tr);
        t0.foo<int>();
    }
};

template <typename T>
struct test3 {
    void method() {
        m.foo<int>();
    }
    my m;
};

template <typename T>
struct test4 {
    void method() {
        auto tr = std::forward_as_tuple(m);
        auto& t0 = std::get<0>(tr);
        t0.foo<int>();          // error: use 'template' keyword to treat 'foo' as a dependent template name
        t0.template foo<int>(); // OK
    }
    my m;
};

template <typename T>
struct test5 {
    void method() {
        std::tuple<my> tr = std::forward_as_tuple(m);
        auto& t0 = std::get<0>(tr);
        t0.foo<int>();
    }
    my m;
};

template <typename T>
struct test6 {
    void method() {
        auto tr = std::forward_as_tuple(m);
        my& t0 = std::get<0>(tr);
        t0.foo<int>();
    }
    my m;
};


int main() {
    test1();
    test2<int>().method();
    test3<int>().method();
    test4<int>().method();
    test5<int>().method();
    test6<int>().method();
}

test4是一个类模板,但m是非依赖类型。

我尝试编译gcc和clang。 gcc 7.1.0报告错误,但是clang 4.0及更高版本报告了编译错误。

错误

https://wandbox.org/permlink/HTSBJMD2kXwfWObl(clang 4.0) https://wandbox.org/permlink/BcUT8gtaFxwC41c5(clang HEAD)

没有错误

https://wandbox.org/permlink/GjIvZa3i5HB8uh6w(gcc 7.1.0)

哪种行为正确?

1 个答案:

答案 0 :(得分:4)

我会同意你的怀疑。这确实是一个铿锵的错误。

当且仅当template是从属名称时才需要t0。特别是,如果t0取决于T,则需要这样做。这就是T中的test4<T>

现在,t0取决于my m,并且有my::foo<T>,但这是不同范围内的无关T。此外,t0不依赖于my::foo<T>