字符串文字不允许作为非类型模板参数 [英] String literals not allowed as non type template parameters

查看:154
本文介绍了字符串文字不允许作为非类型模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下引用来自Addison Wesley的 C ++ Templates


因为字符串文字是对象,所以你可以帮助我理解 内部链接(两个字符串文字具有相同的值,但在不同的模块中是不同的对象),您不能将它们用作模板参数:



解决方案

你的编译器最终会在 的翻译单位之间的差异。在这些翻译单元中,您可以识别不同的实体:对象,函数等。链接器作业是将这些单元连接在一起,并且该过程的一部分是合并身份。



标识符具有链接 内部链接表示在该翻译单元中命名的实体仅对该翻译单元可见,链接意味着实体对其他单位可见。



当实体被标记为 static 时,它被赋予 internal 所以给定这两个翻译单元:

  // a.cpp 
static void foo(){/ * in a * /}

// b.cpp
static void foo(){/ * in a * /}

foo 中的每一个都指的是一个实体(在这种情况下是一个函数),它只对它们各自的翻译是可见的单位;也就是说,每个翻译单元都有自己的 foo



类型为 static const char [..] 。也就是:

  // str.cpp 
#include< iostream>

//此代码:

void bar()
{
std :: cout< abc< std :: endl;
}

//在概念上等价于:

static const char [4] __literal0 = {'a','b','c',0 };

void bar()
{
std :: cout< __literal0<< std :: endl;
}

正如你所看到的,文字的值是翻译单元内部的。因此,如果您在多个翻译单元中使用abc,那么它们都会成为不同的实体。



总的来说,这意味着这在概念上没有意义:

  template< const char * String> 
struct baz {};

typedef baz<abc>不相干的

因为abc不同。每个翻译单元将被给予不同的类,因为每个abc是不同的实体,即使它们提供了相同参数。 / p>

在语言层面上,这是通过说模板非类型参数可以是指向具有外部链接的实体的指针;

因此,这是很好的:

  // good.hpp 
extern const char * my_string;

// good.cpp
const char * my_string =any string;

// anything.cpp
typedef baz< my_string>相干; // 好的;所有实例化使用相同的实体






有联系;一些没有,例如函数参数。



优化编译器将相同的字面量存储在同一地址,以节省空间;但这是实施细节的质量,而不是保证。


The following quote is from C++ Templates by Addison Wesley. Could someone please help me understand in plain English/layman's terms its gist?

Because string literals are objects with internal linkage (two string literals with the same value but in different modules are different objects), you can't use them as template arguments either:

解决方案

Your compiler ultimately operates on things called translation units, informally called source files. Within these translation units, you identify different entities: objects, functions, etc. The linkers job is to connect these units together, and part of that process is merging identities.

Identifiers have linkage: internal linkage means that the entity named in that translation unit is only visible to that translation unit, while external linkage means that the entity is visible to other units.

When an entity is marked static, it is given internal linkage. So given these two translation units:

// a.cpp
static void foo() { /* in a */ } 

// b.cpp
static void foo() { /* in a */ } 

Each of those foo's refer to an entity (a function in this case) that is only visible to their respective translation units; that is, each translation unit has its own foo.

Here's the catch, then: string literals are the same type as static const char[..]. That is:

// str.cpp
#include <iostream>

// this code:

void bar()
{
    std::cout << "abc" << std::endl;
}

// is conceptually equivalent to:

static const char[4] __literal0 = {'a', 'b', 'c', 0};

void bar()
{
    std::cout << __literal0 << std::endl;
}

And as you can see, the literal's value is internal to that translation unit. So if you use "abc" in multiple translation units, for example, they all end up being different entities.

Overall, that means this is conceptually meaningless:

template <const char* String>
struct baz {};

typedef baz<"abc"> incoherent;

Because "abc" is different for each translation unit. Each translation unit would be given a different class because each "abc" is a different entity, even though they provided the "same" argument.

On the language level, this is imposed by saying that template non-type parameters can be pointers to entities with external linkage; that is, things that do refer to the same entity across translation units.

So this is fine:

// good.hpp
extern const char* my_string;

// good.cpp
const char* my_string = "any string";

// anything.cpp
typedef baz<my_string> coherent; // okay; all instantiations use the same entity


†Not all identifiers have linkage; some have none, such as function parameters.

‡ An optimizing compiler will store identical literals at the same address, to save space; but that's a quality of implementation detail, not a guarantee.

这篇关于字符串文字不允许作为非类型模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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