模板基类成员出现g++编译器错误

g++ compiler error with templated base class member

本文关键字:g++ 编译器 错误 基类 成员      更新时间:2023-10-16

我正在尝试使用g++编译一些Microsoft Visual C++代码。现在我遇到了一个编译器错误,我真的无法理解。(简化的)代码如下:

template<int X> struct A {
    template<class Ret> static Ret call() {
        return 0;
    }
};
template<int X> struct B : A<X> {
    int f() {
        return A<X>::call<int>();
    }
};

当我试图用g++(版本4.4.5)编译它时,我得到了以下错误:

main.cpp: In member function int B<X>::f(): 
main.cpp:16: error: expected primary-expression before int 
main.cpp:16: error: expected ; before int
main.cpp:16: error: expected unqualified-id before > token

如果我从方法A::调用中删除模板类型(Ret),代码编译得很好。有人能看到这里出了什么问题吗?

谢谢!

您需要template关键字:

return A<X>::template call<int>();

call是一个依赖名称,这意味着它的含义取决于一个模板参数,而当编译器处理f()时,这个参数是未知的。您需要通过在call前面加上template关键字来指示它是一个函数模板。

当您尝试访问嵌套类型时也会发生同样的事情:您需要添加typename关键字来指示名称表示类型:

template <typename T>
struct A { typedef int type; };
template <typename T>
void f()
{
    typename A<T>::type i = 0; // notice "typename" here
}

有时你甚至需要混合两者:

template <typename T>
struct A
{
    template <typename U>
    struct inner { };
};
template <typename T>
void f()
{
    typename A<T>::template inner<int> var;
}

这两个关键词的使用在这个问题的答案中得到了充分的解释:我必须把"模板"answers"typename"关键词放在哪里以及为什么?(感谢@Björn Pollex找到链接)。

A是一个模板,在不知道X的情况下,编译器无法确定A<X>的内容。尤其是它不知道call最终会成为一个模板。

要告诉编译器,您必须使用template关键字:

template<int X> struct B : A<X> {
    int f() {
        return A<X>::template call<int>();
    }
};

您必须指定您调用的函数是一个模板,因为它是模板类的一部分。编译器不知道任何给定的A<X>都有一个名为call的模板函数,因此您需要帮助它

template<int X> struct B : A<X> {
    int f() {
        return A<X>::template call<int>();
    }
};