Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板、数组和常量表达式_C++_Templates_Constant Expression_Template Argument Deduction - Fatal编程技术网

C++ 模板、数组和常量表达式

C++ 模板、数组和常量表达式,c++,templates,constant-expression,template-argument-deduction,C++,Templates,Constant Expression,Template Argument Deduction,考虑以下代码: template<char> struct S { }; template<int N> constexpr auto f(const char (&ref) [N]) { return S<ref[0]>{}; } int main() { constexpr auto v = f("foo"); (void)v; } 它们是否都应该编译,还是因为或多或少相同的原因而无法编译 从中我们可以看出: 条件表

考虑以下代码:

template<char>
struct S { }; 

template<int N>
constexpr auto f(const char (&ref) [N]) {
    return S<ref[0]>{};
}

int main() {
    constexpr auto v = f("foo");
    (void)v;
}
它们是否都应该编译,还是因为或多或少相同的原因而无法编译

从中我们可以看出:

条件表达式
e
是核心常量表达式,除非对
e
[…]的求值将求值下列表达式之一:
[…]
-引用引用类型的变量或数据成员的id表达式,除非该引用具有前面的初始化且
-使用常量表达式或
-其寿命开始于
e
的评估

无论如何,在这种情况下,它是用常量表达式初始化的,生命周期与
e
相同,因此该规则不适用

我的推理有什么问题


作为一个附带问题,我想问一下是否可以使用这样一个数组或它的一部分作为模板参数。

第一个示例不应该编译,因为您不能只使用compiletime constexpr函数(或在编译时重载,如D)

按照这个推理,如果您在运行时调用第一个示例的
f
,它的返回类型是什么

至于附带的问题:Boost Hana尽管只支持最新的标准,但只在运行时使用字符串文字,因此这可能是不可能的。

template<int N>
constexpr auto f(const char (&ref) [N]) {
    return S<ref[0]>{};
}

没有所需的转换常量表达式-该表达式是由模板非类型参数引入的。这段代码很好,只有在尝试使用非
constexpr
数组值初始化
constexpr
变量时才会出现问题

请注意,constexpr函数仍然可以在运行时调用,并且不能在运行时实例化
S
。@kennytm注意,我将其称为
constexpr auto v=f(“foo”)
。没关系,其他人可以称之为
chara[10];随机化(a);我明白你的意思。因此,没有机会将其用作模板参数?我认为在一般情况下不可能这样做,但如果您使用的是g++,则可以在中使用它的扩展
template<int N>
constexpr auto f(const char (&ref) [N]) {
    return S<ref[0]>{};
}
template<int N>
constexpr auto f(const char (&ref) [N]) {
    return ref[0];
}