代码保护失败和模板从字符串文字 [英] code guards fail and template from string literal

查看:225
本文介绍了代码保护失败和模板从字符串文字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道将字符串文字作为模板参数传递的唯一方法是在之前声明:

I know the only way to pass a string literal as template argument is to declare it before:

文件啊

#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

文件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 can't declare EL as external and I want to keep the a.cpp. Solutions?

推荐答案

让我们从标准中为所有人的利益开始,从14.3.2模板非类型参数[ temp.arg.nontype](C ++ 03 Standard):

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):


1非类型非模板的模板参数模板参数
应为以下之一:

1 A template-argument for a non-type, non-template template-parameter shall be one of:

- 整数的常数表达式或
枚举类型;或

— an integral constant-expression of integral or enumeration type; or

- 非类型模板参数的名称;或

— the name of a non-type template-parameter; or

- 包含外部链接的对象或函数的地址,包括
函数模板和函数模板ID, -static
类成员,表示为& id-expression 其中&如果
的名称引用一个函数或数组
,或者如果相应的
template-parameter是引用,则是可选的;或

the address of an object or function with external linkage, including function templates and function template-ids but excluding non-static class members, expressed as & id-expression where the & is optional if the name refers to a function or array, or if the corresponding template-parameter is a reference; or

- 指向成员表达的
的指针,如第5.3.1节所述。

— a pointer to member expressed as described in 5.3.1 .

强调我的相关部分。

此外,第5段列出了允许的转换,其中一个是指针衰减的数组。第2段甚至是一个注释,显示与

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.

类似的使用 char * 是左边是如何有一个对象在一个标题与外部链接和没有错误。通常的方式是在标题中声明,在一个TU中只有一个定义。

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.

// In header
extern char EL[]; // array of unspecified size, an incomplete type
                  // extern char EL[3] is acceptable, too.

// In source
char EL[] = "el";

请注意, static 的要求,对象有外部链接。

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.

// In header
// NOT RECOMMENDED! Be wary of ODR-violations with such constructs
// or simply only use these in source files
namespace {

// Recommend using const here, which in turn means using extern
// change non-type template parameter accordingly
extern const char EL[] = "el";

} // namespace






对于好奇,C ++ 0x放松了对象具有外部链接作为有效参数的要求。 (我的GCC副本不支持。)字符串文字不可避免地仍然禁止显示为模板参数。


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.

这篇关于代码保护失败和模板从字符串文字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆