代码保护失败并且模板来自字符串文字
我知道传递字符串文字作为模板参数的唯一方法是在之前声明它:
file ah
#ifndef A_H
#define A_H
#include <string>
char EL[] = "el";
template<char* name>
struct myclass
{
std::string get_name() { return name; }
};
typedef myclass<EL> myclass_el;
#endif
file a.cpp
#include "a.cpp"
main.cpp
#include "a.h"
...
g++ -c a.cpp
g++ -c main.cpp
g++ -o main main.o a.o
,我得到:
a.o:(.data+0x0): multiple definition of `EL'
main.o:(.data+0x0): first defined here
collect2: ld returned 1 exit status
我不能将 EL
声明为外部,我想要保留a.cpp
。解决方案?
I know the only way to pass a string literal as template argument is to declare it before:
file a.h
#ifndef A_H
#define A_H
#include <string>
char EL[] = "el";
template<char* name>
struct myclass
{
std::string get_name() { return name; }
};
typedef myclass<EL> myclass_el;
#endif
file a.cpp
#include "a.cpp"
main.cpp
#include "a.h"
...
g++ -c a.cpp
g++ -c main.cpp
g++ -o main main.o a.o
and I got:
a.o:(.data+0x0): multiple definition of `EL'
main.o:(.data+0x0): first defined here
collect2: ld returned 1 exit status
I can't declare EL
as external and I want to keep the a.cpp
. Solutions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
让我们从标准所说的为了所有人的利益开始,从 14.3.2 模板非类型参数 [temp.arg.nontype](C++03 标准)开始:
强调我的相关部分。
此外,第 5 段列出了允许的转换,其中之一是数组到指针的衰减。第 2 段甚至是一个注释,展示了与 OP 类似的 char* 用法。
剩下的就是如何在标头中包含一个具有外部链接且没有错误的对象。通常的方式是在标头中声明,并且在一个 TU 中只有一个定义。
请注意,由于对象具有外部链接的要求,因此不可能使用
static
。如果意图是每个 TU 有一个单独的对象,则首选未命名名称空间。出于好奇,C++0x 放松了对象具有外部链接作为有效参数的要求。 (我的 GCC 副本还不支持这一点。)字符串文字仍然莫名其妙地被禁止作为模板参数出现。
Let's start with what the Standard says for the benefit of all, from 14.3.2 Template non-type arguments [temp.arg.nontype] (C++03 Standard):
Emphasis mine for the relevant parts.
Additionally, paragraph 5 lists the conversions that are allowed and one of them is array to pointer decay. Paragraph 2 is even a note that showcases a similar use of
char*
as that of the OP.All that is left is how to have an object in a header with external linkage and no errors. The usual way is a declaration in the header, and one and only one definition in one TU.
Note that
static
is not a possibility because of the requirement that the object have external linkage. The unnamed namespace is to be preferred if the intent is to have a separate object per TU.For the curious, C++0x relaxed the requirement that an object have external linkage to be a valid parameter. (My copy of GCC doesn't support that yet.) String literals are inexplicably still forbidden to appear as template arguments.
修改后的答案(之前的答案是废话。抱歉!另外,你之前的问题应该已经完全涵盖了这个问题。)
标题:
你需要一个 TU 来定义
EL
:您可以在任何地方使用该模板:
Revised Answer (The previous answer was nonsense. Sorry for that! Also, your previous question should have covered this problem already entirely.)
Header:
You need one TU to define
EL
:You can use the template anywhere: