g++模板化基类成员的编译器错误

发布于 2024-12-28 19:03:09 字数 694 浏览 4 评论 0原文

我正在尝试使用 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::call 中删除模板类型 (Ret),则代码仅编译美好的。有人能看出这里出了什么问题吗?

谢谢!

I'm trying to compile some Microsoft Visual C++ code using g++. Now I've come across a compiler error which I really can't understand. The (simplified) code looks like this:

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

When I try to compile this with g++ (version 4.4.5), I get the following error:

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

If I remove the template type (Ret) from method A::call, the code compiles just fine. Can anybody see whats wrong here?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

╰ゝ天使的微笑 2025-01-04 19:03:09

您需要 template 关键字:

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

call 是一个依赖名称,这意味着它的含义取决于模板参数,而编译器处理 f() 时不知道该模板参数。您需要通过使用 template 关键字作为前缀来表明 call 是一个函数模板。

当您尝试访问嵌套类型时,也会发生同样的事情:您需要添加 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;
}

这两个的使用关键字在这个问题的答案中得到了彻底的解释:我必须在哪里以及为什么必须放置“template”和“typename”关键字?(感谢@Björn Pollex 找到了链接)。

You need the template keyword:

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

call is a dependent name, meaning that its signification depends on a template parameter, which is not known when the compiler process f(). You need to indicate that call is a function template by prefixing it with the template keyword.

The same thing happens when you try to access a nested type: you need to add the typename keyword to indicate that the name denotes a type:

template <typename T>
struct A { typedef int type; };

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

And sometimes you even need to mix both:

template <typename T>
struct A
{
    template <typename U>
    struct inner { };
};

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

The use of these two keywords is thoroughly explained in the answers to this question: Where and why do I have to put the “template” and “typename” keywords? (thanks to @Björn Pollex for finding the link).

执妄 2025-01-04 19:03:09

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

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

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

A is a template, and without knowing X the compiler can't determine the contents of A<X>. Especially it doesn't know that call will end up being a template.

To tell that to the compiler you have to use the template keyword:

template<int X> struct B : A<X> {
    int f() {
        return A<X>::template call<int>();
    }
};
淡淡绿茶香 2025-01-04 19:03:09

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

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

You have to specify that the function you're calling is a template, as it's part of a template class. The compiler is not aware that any given A<X> has a template function named call, and therefore you need to help it.

template<int X> struct B : A<X> {
    int f() {
        return A<X>::template call<int>();
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文