gpt4 book ai didi

c++ - g++ 不喜欢模板 var 上的模板方法链接?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:53:53 25 4
gpt4 key购买 nike

我正在尝试使用 g++ 编译一些以前在 Visual C++ 2008 Express Edition 下开发的代码,看起来 g++ 不允许我调用模板方法在模板变量的方法返回的引用上。我能够将问题缩小到以下代码:

class Inner
{
public:
template<typename T>
T get() const
{
return static_cast<T>(value_);
};
private:
int value_;
};

class Outer
{
public:
Inner const& get_inner() { return inner_; };
private:
Inner inner_;
};

template<typename T>
int do_outer(T& val)
{
return val.get_inner().get<int>();
}

int main()
{
Outer outer;
do_outer(outer);
return 0;
}

这段代码在微软的编译器下可以正常编译,但是 g++ 会抛出一个错误:

$ g++ -c main.cpp
main.cpp: In function ‘int do_outer(T&)’:
main.cpp:24: error: expected primary-expression before ‘int’
main.cpp:24: error: expected ‘;’ before ‘int’
main.cpp:24: error: expected unqualified-id before ‘>’ token

第 24 行指的是 return val.get_inner().get<int>(); .

如果我做 do_outer接收 Outer 的正常方法引用代码编译。制作Inner::get()一个正常的方法也有效。并制作Inner::get()返回 void 并接收模板参数也有效,因为下面的 int 说明符变得不需要了,即:

class Inner
{
public:
template<typename T>
void get(T& val) const
{
val = static_cast<T>(value_);
};
private:
int value_;
};

...

template<typename T>
int do_outer(T& val)
{
int i;
val.get_inner().get(i);
return i;
}

...

(g++ 不会提示上面的代码。)

现在我没主意了。有什么问题? gcc/g++ 有问题吗?我的代码是否存在合规性问题?

我使用的编译器是:

$ g++ --version
g++ (Ubuntu 4.3.3-5ubuntu4) 4.3.3

最佳答案

只是为了提供一些关于为什么 template 的背景。需要关键字:

template<typename T>
int do_outer(T& val)
{
int i;
val.get_inner().get<int>(i);
return i;
}

当编译器看到这个函数时,它不知道val的类型是什么是。因此它解析行 val.get_inner().get(i)如下:

1:val .

编译器看到 .因此可以假设“val”具有类类型,下一个标识符是成员对象或函数的名称。

<强>2。 val . get_inner (

get_inner是成员的名称,然后编译器会看到 ( .唯一的可能性是 get_inner是一个函数名,所以这是一个函数调用。然后它解析参数,直到找到结束符 )。 .

<强>3。 val . get_inner () .

至于第一步,它现在知道 get_inner 的返回必须是类类型,因此它知道下一个标识符是成员对象或函数。

<强>4。 val . get_inner () . get <

那么,< 可以做什么?可能是什么意思当然它是模板参数的开始......或者它可能是小于运算符?

我们知道get只能是对象或函数。如果它是一个对象,那么 <作为小于运算符非常有意义。此外,标准或多或少指出只有在 < 之前的名称是 template-name它会治疗<吗作为模板参数 (14.2/3):

After name lookup (3.4) finds that a name is a template-name, if this name is followed by a <, the < is always taken as the beginning of a template-argument-list and never as a name followed by the less-than operator.

在这种情况下,编译器不知道表达式 val.get_inner() 的类型是什么是所以它不能查找get .它或多或少地假设它是一个成员对象而不是模板名称。 '<' 被视为小于运算符,编译器最终检查是否 get小于 int - 因此错误。

那么,为什么修复会起作用?

添加 template关键字

从字面上看,我们是在告诉编译器 get是一个模板名称,所以 <运算符被视为模板参数列表的开始。

移除模板参数

当 do_outer 没有模板参数时即:val . get_inner () . get (编译器期望成员 get是一个对象或一个函数。 (消除这两者之间的歧义,名称被视为一个函数。稍后模板参数推导然后计算出模板参数的类型。

关于c++ - g++ 不喜欢模板 var 上的模板方法链接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1574721/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com