简体   繁体   English

标准对作为模板参数的 char 数组有何看法?

[英]What does the standard say about char arrays as template arguments?

During my research for an answer for this question I found (I did not know that before) that gcc and clang allow char arrays to be template arguments if they are declared static .在我研究这个问题的答案时,我发现(我之前不知道)gcc 和 clang 允许char数组作为模板参数,如果它们被声明为static Eg this code compiles with gcc and clang:例如,这段代码用 gcc 和 clang 编译:

#include <type_traits>

template <int N, const char (&string)[N]>
auto foo()
{
    if constexpr (string[0] == 'i')
        return 0;
    else
        return 3.14f;
}

void bar()
{
    static constexpr char string1[] = "int";
    static constexpr char string2[] = "float";

    auto i = foo<sizeof(string1), string1>();
    auto f = foo<sizeof(string2), string2>();

    static_assert(std::is_same_v<decltype(i), int>);
    static_assert(std::is_same_v<decltype(f), float>);
}

MSVC also allows that. MSVC 也允许这样做。 However, to make it work with MSVC, I have to declare the two strings in the global namespace.但是,要使其与 MSVC 一起使用,我必须在全局命名空间中声明这两个字符串。 Then it works just as well.然后它也能正常工作。

So my question is: What does the standard say about this?所以我的问题是:标准对此有何看法? Which compiler (if any) is right?哪个编译器(如果有)是正确的?


Update:更新:

This issue has been fixed in VS 2019 version 16.4 (msvc v19.24): https://developercommunity.visualstudio.com/content/problem/341639/very-fragile-ice.html此问题已在 VS 2019 版本 16.4 (msvc v19.24) 中修复: https : //developercommunity.visualstudio.com/content/problem/341639/very-fragile-ice.html

This is a change from C++14 to C++17 that looks like MSVS hasn't caught up with.这是从 C++14 到 C++17 的变化,看起来 MSVS 没有赶上。 Previously in [temp.arg.nontype] a non type argument had to be以前在[temp.arg.nontype] 中,非类型参数必须是

A template-argument for a non-type, non-template template-parameter shall be one of:非类型、非模板模板参数的模板参数应为以下之一:

  • for a non-type template-parameter of integral or enumeration type, a converted constant expression ([expr.const]) of the type of the template-parameter;对于整数或枚举类型的非类型模板参数,模板参数类型的转换常量表达式([expr.const]); or或者

  • the name of a non-type template-parameter;非类型模板参数的名称; or或者

  • a constant expression ([expr.const]) that designates the address of a complete object with static storage duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as & id-expression, where the id-expression is the name of an object or function, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference;一个常量表达式 ([expr.const]),它指定一个完整的对象的地址,具有静态存储持续时间和外部或内部链接,或者一个具有外部或内部链接的函数,包括函数模板和函数模板 ID,但不包括非静态类成员,表示(忽略括号)为 & id-expression,其中 id-expression 是对象或函数的名称,但如果名称是指函数或数组,则可以省略 &,如果对应的名称,则应省略模板参数是一个参考; or或者

  • a constant expression that evaluates to a null pointer value ([conv.ptr]);计算结果为空指针值的常量表达式 ([conv.ptr]); or或者

  • a constant expression that evaluates to a null member pointer value ([conv.mem]);计算结果为空成员指针值 ([conv.mem]) 的常量表达式; or或者

  • a pointer to member expressed as described in [expr.unary.op];一个指向成员的指针,如 [expr.unary.op] 中所述; or或者

  • a constant expression of type std::nullptr_t .类型为std::nullptr_t的常量表达式。

emphasis mine强调我的

and because of bullet 3 you could not use a block scope variable as block scope variables have no linkage per [basic.link]/10并且由于第 3 条,您不能使用块作用域变量,因为块作用域变量根据[basic.link]/10没有链接

Names not covered by these rules have no linkage.这些规则未涵盖的名称没有链接。 Moreover, except as noted, a name declared at block scope has no linkage.此外,除非另有说明,在块范围内声明的名称没有链接。

In C++17 this changes.在 C++17 中,这发生了变化。 [temp.arg.nontype] now has [temp.arg.nontype]现在有

A template-argument for a non-type template-parameter shall be a converted constant expression of the type of the template-parameter.非类型模板参数的模板参数应是模板参数类型的转换常量表达式。 For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of):对于引用或指针类型的非类型模板参数,常量表达式的值不得引用(或对于指针类型,不得为以下地址):

  • a subobject,一个子对象,

  • a temporary object,一个临时对象,

  • a string literal,字符串文字,

  • the result of a typeid expression, or typeid 表达式的结果,或

  • a predefined预定义的­ func__ variable. func__ 变量。

This now allows you to use a block scope static variable这现在允许您使用块范围静态变量

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C++20 标准对使用子对象作为模板非类型 arguments 有什么看法? - What does the C++20 standard say about usage of subojects as template non-type arguments? 标准对未对齐的内存访问有何看法? - What does the standard say about unaligned memory access? 标准对lambda类型的命名空间有何看法? - What does the Standard say about the namespace of lambda types? C++ 标准对堆栈溢出有何规定? - What does the C++ standard say about stack overflow? 标准对这个指向成员函数类型的模板参数有什么看法? 我的代码是错误的,还是 MSVS 16.6 有问题? - What does the standard say about this pointer-to-member-function type template parameter? Is my code wrong, or is MSVS 16.6 buggy? 可变列表与单个模板参数:标准说什么? - variadic list vs single template parameter: what does the standard say? 标准对于std :: pow,std :: log等cmath函数有什么看法? - What does standard say about cmath functions like std::pow, std::log etc? C ++语言标准对static_cast如何处理减小整数大小有何看法? - What does the C++ language standard say about how static_cast handles reducing the size of an integer? 在MoveAssignable的情况下,标准对移动分配给自己有什么看法? - What does the standard say about move-assignment to self in the case of MoveAssignable? 关于移动活动对象存储,C ++标准怎么说? - What does C++ standard say about moving live object storage?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM