如何解析模板静态成员函数? [英] How are templated static member functions parsed?

查看:96
本文介绍了如何解析模板静态成员函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从来没有得到一个很好的解释,如何模板参数扣除真的有效,所以我不知道如何解释我在下面看到的行为:

I have never gotten a great explanation of how template argument deduction really works, so I'm not sure how to explain behavior I'm seeing in the following:

template<typename T>
struct Base
{
protected:
    template<bool aBool = true>
    static void Bar(int)
    {
    }
};

template<typename T>
class Derived : public Base<T>
{
public: 
    void Foo() { Base<T>::Bar<false>(5); } 
};

int main()
{
    Derived<int> v;
    v.Foo();
    return 0;
}

此代码不会构建,并给出错误:

This code won't build, and gives the error:

main.cpp: In instantiation of 'void Derived<T>::Foo() [with T = int]':
main.cpp:25:8:   required from here main.cpp:19:15: error: invalid
operands of types '<unresolved overloaded function type>' and 'bool'
to binary 'operator<'



如果您更改2 Base< T> s in Derived to Base< int> ,它编译。如果您将 Bar()调用到 Base< T> :: template Bar< false>(5); ,它也编译。

If you change the 2 Base<T>s in Derived to Base<int>, it compiles. If you change the call to Bar() to Base<T>::template Bar<false>(5);, it also compiles.

我看到的一个解释是,编译器不知道Bar是一个模板,可能是因为它不知道Base是什么直到宣布Derived的专业化。但是一旦编译器开始生成 Foo()的代码,已经定义了 Base< T> Bar 。是什么导致编译器假设符号 Bar 不是模板,并尝试应用 operator< / code>而不是?

The one-liner I saw as an explanation for this is that the compiler doesn't know that Bar is a template, presumably because it doesn't know what Base is until a specialization of Derived is declared. But once the compiler starts generating code for Foo(), Base<T> has already been defined, and the type of Bar can be determined. What is causing the compiler to assume the symbol Bar is not a template, and attempting to apply operator<() instead?

我认为它与在编译过程中评估模板时的规则 - 我猜我在找什么是一个很好的全面解释这个过程,这样下次我跑到下面的代码,我可以推导出答案没有好人的堆栈溢出的帮助。

I assume it has to do with the rules of when templates are evaluated in the compilation process - I guess what I'm looking for is a good comprehensive explanation of this process, such that the next time I run into code like the below, I can deduce the answer without the help of the good people on stack overflow.

注意我使用g ++ 4.7编译,支持c ++ x11。

Note I'm compiling with g++ 4.7, with c++x11 support.

推荐答案

void Foo() { Base<T>::Bar<false>(5); } 

在此上下文中 Base< T> 是依赖名称。要访问依赖名称的成员模板,您需要添加模板关键字:

In this context Base<T> is a dependent name. To access a member template of a dependent name you need to add the template keyword:

void Foo() { Base<T>::template Bar<false>(5); } 

否则 Base< T> :: Bar 将被解析为非模板成员,< 作为小于

Otherwise Base<T>::Bar will be parsed as a non-template member and < as less-than.

为什么需要模板,原因是两阶段查找。错误在第一遍期间被触发, 之前,类型被替换,因此编译器不会 Base< T> 。例如,您为 int 添加了具有非模板 Bar Bar 成员(例如, int 成员)。在将 T 替换为 Foo 之前,编译器不知道是否有类型的特殊化。

As of why the template is required, the reason is two-phase lookup. The error is triggered during the first pass, before the type is substituted, so the compiler does not know what is the definition of Base<T>. Consider for example that you added an specialization of Bar for int that had a non-template Bar member (say for example an int member). Before substituting T into Foo, the compiler does not know if there is an specialization for the type.

这篇关于如何解析模板静态成员函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆