C++标准是否定义了结构中成员函数的函数内定义是否必须具有静态链接?
Does the C++ standard define if in-function definitions of member functions in structs must have static linkage?
我在函数中定义的结构中定义了一个静态函数。我想获取指向内部函数的模板函数指针。
请考虑以下示例:
template <class Func, Func GetToken>
struct token_user {
void foo () { GetToken(); } // Do something with token.
};
struct generator_out {
constexpr static const auto get_token() {return 0;}
};
int main() {
struct generator_in {
constexpr static const auto get_token() {return 0;}
};
// Works fine
token_user<decltype(&generator_out::get_token), &generator_out::get_token>();
// Fails with GCC, works with clang and msvc
token_user<decltype(&generator_in::get_token), &generator_in::get_token>();
}
我用我的本地 MSVC 2017 编译器以及 wandbox.org 上的 clang 6.0 和 gcc 8.1 编译器对此进行了测试。MSVC和clang工作,gcc不工作。
谁是正确的?是 clang 和 msvc 太宽容了,扭曲了 c++ 标准,还是 gcc 根本没有实现这一点?(或者它甚至可能是一个错误?标准对此有何规定?
编辑: 来自 gcc 的错误消息:
prog.cc: In function 'int main()':
prog.cc:15:76: error: 'main()::generator_in::get_token' is not a valid template argument for type 'const int (*)()' because 'static constexpr const auto main()::generator_in::get_token()' has no linkage
token_user<decltype(&generator_in::get_token), &generator_in::get_token>(); // Fails with GCC, works with clang and msvc
GCC 是正确的,generator_in::get_token
没有链接,不能在声明它的范围之外使用,因此不能用作实例化token_user
的参数。
请参阅 [basic.link]/8 和/9(我只包括相关部分(:
。除非另有说明,否则在块范围内声明的名称没有链接。
例:
void f() { struct A { int x; }; // no linkage }
这很重要,因为成员函数具有类的链接。 [basic.link]/5:
。成员函数、静态数据成员、类范围的命名类或枚举,或在类范围 Typedef 声明中定义的未命名类或枚举,使得类或枚举具有用于链接目的的 typedef 名称 ([dcl.typedef](,与它所属的类的名称具有相同的链接(如果有(。
所以generator_in
和generator_in::get_token
都没有联系。
最后: [basic.link]/2.3:
— 当名称没有链接时,它所表示的实体不能由其他范围的名称引用。
相关文章:
- 此递归模板类型定义是否有效C++?
- 虚拟成员函数的定义是否强制在同一转换单元中动态初始化静态数据成员?
- 越界成员函数定义是否需要一个完全限定的类名,直到全局范围
- C++标准是否定义了结构中成员函数的函数内定义是否必须具有静态链接?
- 带有"struct structname<..>"的模板定义是否正确?
- NTRUEncrypt:使用开源标准算法中的描述无法正确找到两个多项式的GCD,无法定义是否存在多边形的逆
- 定义重载C++函数模板的原型时,使用其名称引用以前的定义是否合法?
- 命名空间的定义是否可以跨越多个翻译单元
- 头文件中的类声明和定义是否在每个包含上编译
- 这个无括号的C预处理器定义是否安全
- char的实现定义是否会影响std::string
- 对内联函数有不同的定义是否是一种未定义的行为
- 同一字符串的多个#定义是否使用相同的常量字符串
- 根据编译时常量,使用相同的标识符 #define 或类型定义是否被认为是可接受的做法?
- 显式模板实例化定义是否也抑制隐式实例化
- 构造函数定义是否可以以 "class" 关键字为前缀?
- 类中的函数定义是否占用类大小的一部分?
- 名称空间作用域构造函数定义是否需要类限定的标识符
- i=i++;未定义.是否i=foo(i++)也未定义
- "volatile"的定义是否如此不稳定,还是 GCC 存在一些标准合规性问题?