已注入类模板的类名
Injected-class-names of class templates
本文关键字:注入 更新时间:2023-10-16
受此答案中代码的启发。考虑:
template<class>
class A { };
int main()
{
A<float> a(A<float>::A<int>());
return 0;
}
这个代码是吗
- 格式错误,因为
A<float>::A
命名构造函数(根据§3.4.3.1[class.qual]/p2),并且不能在此上下文中使用(加上<int>
无论如何都会完全解析失败),或者 - 格式良好,
A<float>::A
是注入的类名,用作模板名(§14.6.1[temp.local]),因此A<float>::A<int>
的含义与A<int>
完全相同,而a
被声明为函数(由于最麻烦的解析)
g++表示1。clang说2,ICC 13也是。哪个编译器是正确的?
gcc
正确;你的代码片段格式不正确
// reduced testcase
template<class T>
class A { };
int main () {
A<float>::A<int> x; // ill-formed, bug in `clang` and `icc`
}
在上面的简化测试用例中,我们有一个嵌套的名称说明符,A<float>::
,后面跟着一个不合格的idA
,后面跟着一些胡言乱语(<int>
)。
这是因为嵌套名称说明符出现的上下文要求在查找过程中包括函数名(意味着首先找到构造函数,并且表达式格式不正确)。
相关错误报告:
- llvm.org/bugs/-#8263;构造函数名称解析不正确
如何规避"问题"
在某些上下文中,通过嵌套名称说明符(指定类)查找的成员名称不应包括函数(因此,在找不到构造函数的上下文中),以下是几个示例:
template<class T>
struct A {
typedef T value_type;
};
struct A<float>::A<int> x; // ok, context: elaborate-type-specifier
typename A<float>::A<int> (); // ok, context: [expr.type.conv]p1
A<float>::A::value_type x; // ok, context: nested-name-specifier
struct X : A<float>::A<int> { }; // ok, context: base-specifier
标准是怎么说的
3.4.3.1p2
类成员[class.qual]
在函数名不被忽略的查找中88和嵌套名称说明符指定一个类C:
- 如果在C中查找时,在嵌套名称说明符之后指定的名称是C的注入类名(第9条),或者
- 在作为成员声明的using声明(7.3.3)中,如果在嵌套名称说明符之后指定的名称与*嵌套名称说明符的最后一个组件中的identifier或简单模板id的模板名称相同
该名称被认为是为类C的构造函数命名。
[注意:…]
此类构造函数名称只能在命名构造函数的声明的声明符id中使用,或在使用声明时使用。
88.忽略函数名的查找包括出现在嵌套名称说明符、详细类型说明符或基说明符TR
14.6.1p2
本地声明的名称[temp.local]
与普通(非模板)类一样,类模板有一个注入的类名(第9条)。注入的类名可以用作模板名或键入名称。
当它与模板参数列表一起使用时,作为模板模板参数的模板自变量,或作为最终参数友元类模板的详细说明的类型说明符中的标识符声明,它引用类模板本身。
否则,就是等效于CCD_ 15中包含的类模板。
相关文章:
- 无法使用加载库卸载注入的 dll (C++)
- 将 dll 文件注入 UWP
- 将具有固定签名的自定义函数名称注入 CRTP
- 发生注入类名时会发生什么情况?(C++)
- 作为指针注入类后重新创建堆栈对象不好吗?
- 如何使用可视化代码和平台IO将环境变量注入CPP文件?
- 限定的依赖名称查找,其中包含基类的注入类名
- 如何在窗口中使用注入的 dll 中的参数调用函数
- PostgresSQL - SQL Ready 语句与字符串转义,防止 SQL 注入攻击
- Windows 将标准的 C 文件结构注入到正在运行的进程中
- 当注入程序的内存空间时,如何读取从 0 到 0xFFFFFFFFF 的每个字节?我正在创建模式扫描仪
- 读取进程内存多级指针(DLL 注入)
- 如何在不诉诸依赖注入的情况下模拟遗留函数?
- c++ 注入器运行,但不注入 DLL
- 为什么我的DLL只能注入手动映射
- 类成员和依赖项注入的对象与引用
- 注入类名作为类型
- C++如何在派生类上进行依赖项注入
- 如何仅在一个窗口中忽略注入的输入?
- DLL 注入不断失败,出现不一致的错误