vso*_*tco 7 c++ templates c++11
这个问题是将成员函数从基类移动到派生类的后续操作
,没有明显的原因打破程序(这是为什么不应该使用它的一个主要例子using namespace std;)
答案建议通过this->依赖模板名称进行限定(这确实是引用此类依赖成员时的方法).但是,似乎存在问题,因此我将列出一个重现问题的最小示例.
考虑一下代码:
#include <iostream>
#include <bitset>
using namespace std;
template<class T>
struct B
{
T bitset{};
};
template<class T>
struct D : B<T>
{
bool foo()
{
return this->bitset < 32;
}
};
int main(){}
Run Code Online (Sandbox Code Playgroud)
令人困惑的是,即使this->bitset应该引用该成员B<T>::bitset,编译器仍然感到困惑,并认为我们试图引用std::bitset<std::size_t>.错误出现在gcc6和clang3.7上.任何想法为什么会这样?B<T>::bitset尽管有资格证明它.
错误(逐字):
In member function 'bool D<T>::foo(T, std::__cxx11::string)': cpp/scratch/minimal.cpp:24:22: error: invalid use of 'class std::bitset<1ul>'
编辑
这看起来像解析/名称查找错误.如果我们用<任何其他比较运算符替换(感谢@Leon的注释),例如
return this->bitset == 32;
Run Code Online (Sandbox Code Playgroud)
该程序编译.所以我猜在this->bitset < 32解析器中认为我们正在尝试实例化一个模板(<标志),而我们忘了关闭它>.但是再次不知道这确实是一个错误,还是该语言是如何工作的.
tl; dr看起来这是一个深思熟虑的决定,专门用于支持您已经使用的替代语法.
下面标准的近似演练:
this-> B <
^
Run Code Online (Sandbox Code Playgroud)
this->B确实命名,但它是一个模板B<T>,所以继续B 在它自己也命名一些东西,一个类模板 B<T>this->B<T>作为限定符,并且它毕竟不是一个小问题在另一种情况下,
this->bitset
Run Code Online (Sandbox Code Playgroud)
进行相同的,直到第三步,当它意识到有两个不同的东西叫做bitset(模板类成员和类模板),只是放弃.
这是来自我躺着的工作草案,所以不一定是最近的,但是:
3.4.5类成员访问[basic.lookup.classref]
1在类成员访问表达式(5.2.5)中,如果是.或 - > token后面紧跟一个标识符后跟一个<,必须查找标识符以确定<是模板参数列表(14.2)的开头还是小于运算符.首先在对象表达式的类中查找标识符.如果未找到标识符,则在整个postfix-expression的上下文中查找它,并命名一个类模板.如果对象表达式的类中的查找找到模板,则还会在整个后缀表达式的上下文中查找该名称,
- 如果找不到名称,则使用在对象表达式的类中找到的名称,否则使用
- 如果在整个postfix-expression的上下文中找到该名称并且未命名类模板,则使用在对象表达式的类中找到的名称,否则
- 如果找到的名称是类模板,则它应该引用与在对象表达式的类中找到的实体相同的实体,否则程序是不正确的.
因此,在任何表达式中this->id < ...,它必须处理id<...模板标识符的开头(例如this->B<T>::bitset).
它仍然首先检查对象,但如果this->id找到模板,则应用进一步的步骤.在你的情况下,this->bitset可能被认为是一个模板,因为它仍然依赖T,所以它发现冲突,std::bitset并在上面的第三个子弹失败.
| 归档时间: |
|
| 查看次数: |
265 次 |
| 最近记录: |