作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我创建了一个带有静态常量元素的类模板。目的是让模板的每个特化都有自己的静态元素版本/值。这是我的示例代码:
template < typename T > class C
{
public:
static const std::string NAME;
T something;
void printName() { std::cout << NAME << std::endl; }
};
class C1 : public C< int >{};
class C2 : public C< char >{};
template<> const std::string C< int >::NAME{ "my int" }; // compiles
template<> const std::string C< char >::NAME{ "my char" }; // compiles
//template<> const std::string C1::NAME{ "my int" }; // doesn't compile
//template<> const std::string C2::NAME{ "my char" }; // doesn't compile
//const std::string C1::NAME{ "my int" }; // doesn't compile
//const std::string C2::NAME{ "my char" }; // doesn't compile
int main()
{
C1 c1;
C2 c2;
c1.printName();
c2.printName();
std::cout << c1.NAME << " " << c2.NAME << std::endl;
std::cout << C1::NAME << " " << C2::NAME << std::endl;
}
当使用可编译版本时,输出是我所期望的:
my int
my char
my int my char
my int my char
对于未编译的行,错误消息(使用 gcc 4.4)表示
ISO C++ does not permit 'C<int>::NAME' to be defined as 'C1::NAME'
为什么不允许这样做?我的理解是,模板的完全特化在所有(?)方面都是一个类,并且此类具有模板中声明的所有成员。所以我希望能够通过使用范围解析运算符来引用该类的静态成员。显然我可以在初始化之后这样做,就像上面 main 的最后一行一样,但不能在初始化本身中这样做。
谁能提供任何关于为什么以这种方式编写标准的见解?如果标准允许上面的“错误”语法,会出现什么样的问题?
最佳答案
在我看来,您遇到的问题与模板无关。问题是您试图在 nested-name-specifier 而不是原始类中使用派生类来定义静态成员。你会在这里遇到同样的问题:
struct A {
static int x;
};
struct B : A{};
int B::x = 42;
您代码中的 C1
和 C2
不是 C
的完全特化,而是 特化的派生类C
。所以我不知道你在这里期待什么......
关于c++ - 为模板特化初始化静态常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40521790/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!