【问题标题】:Strings as template arguments字符串作为模板参数
【发布时间】:2013-01-10 01:28:51
【问题描述】:

虽然 C++ 标准不允许使用字符串文字作为模板参数,但允许使用以下内容:

ISO/IEC 14882:2011

14.3.2 模板非类型参数 [temp.arg.nontype]

2 [注意:字符串文字(2.14.5)不满足要求 这些类别中的任何一个,因此是不可接受的 模板参数。 [示例:

template<class T, const char* p> class X { / ... / };

X<int, "Studebaker"> x1; // error: string literal as template-argument

const char p[] = "Vivisectionist";
X<int,p> x2; // OK

—结束示例]—结束注释]

那么为什么下面的代码在所有编译器(gcc 4.7.2、MSVC-11.0、Comeau)中都会出现错误?

template <const char* str>
void foo() {}

int main()
{
   const char str[] = "str";
   foo<str>();
}

【问题讨论】:

  • +1 它曾经适用于 MSCV 6 或 7 之类的东西。但上次我尝试它不再编译 :-( 很高兴你问这个问题。

标签: c++


【解决方案1】:

倒退几行。

14.3.2/1:一个常量表达式 (5.19),它指定具有静态存储持续时间和外部或内部链接的对象的地址。

【讨论】:

    【解决方案2】:

    请注意,以下修改有效:

    template <const char* str>
    void foo() {}
    
    char str[] = "str";
    
    int main() {
        foo<str>();
    }
    

    有关简短说明,请参阅http://www.comeaucomputing.com/techtalk/templates/#stringliteral

    【讨论】:

    • 你是对的,删除 const 会有所帮助。但是,我认为它只是演示了代码处理常量中的编译器错误,因为const char p[]="" 仍然定义了一个外部对象。
    • @Cornstalks:哦,是的,const 在这里很重要:比较 ideone.com/rY7ZWIideone.com/u4LbEC(虽然你是对的,但不使用局部变量是必不可少的,我只是在尝试它的变体遇到了const这个东西……)
    • 嗯,我认为标准中的术语是“外部链接”(而不是“外部对象”)。具有声明为const 的命名空间范围的对象具有内部链接。我不是一名优秀的语言律师,但我认为这不是编译器错误。
    • @mkluwe:根据 n.m. 的引用,它需要是一个具有“静态存储持续时间和外部或内部链接”的对象(所以除非const 使其具有非静态存储持续时间,否则它无论是外部链接还是内部链接,理论上都应该有效)。不过,我懒得弄清楚const 是如何影响这一切的。但我会说这是一个编译器错误,因为标准的示例代码失败了:http://ideone.com/YQNCfB
    • @Cornstalks C++03 需要外部链接,并且命名空间范围内的 const 具有内部链接。这不是编译器错误(但有人可能会说这是标准中的错误)。
    猜你喜欢
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    相关资源
    最近更新 更多