当前位置: 首页 > 知识库问答 >
问题:

模板constexpr变量

勾渝
2023-03-14

我想确认这个代码是合法的(还是不合法的?)C++17。

#include <iostream>

template<int N> inline constexpr float MyConst;

template<> inline constexpr float MyConst<1> = 1.1f;
template<> inline constexpr float MyConst<2> = 2.2f;

int main ()
{
    std::cout << MyConst<1> << '\n';

    return 0;
}

如果用G++和MSVC编译,我不会得到错误(并得到正确的输出),

但Intel和clang给出了一个错误:

test.cpp(3): error: missing initializer for constexpr variable
  template<int N> inline constexpr float MyConst;
                         ^

使用-std=C++17编译(对于MSVC/std:C++17)。

在godbolt和我的本地机器上尝试了最新的编译器。

共有1个答案

谢华彩
2023-03-14

必须立即初始化constexpr变量。因此,myconst的模板需要一个initialiser/definition。GCC一开始就不需要定义,这是违反规范的。如果使用变量的非专用形式,例如myconst<3>,您将从gcc得到类似的错误:

<source>: In instantiation of 'constexpr const float MyConst<3>':
<source>:10:18:   required from here
<source>:3:40: error: uninitialized 'const MyConst<3>' [-fpermissive]
    3 | template<int N> inline constexpr float MyConst;
      |                                        ^~~~~~~
ASM generation compiler returned: 1
<source>: In instantiation of 'constexpr const float MyConst<3>':
<source>:10:18:   required from here
<source>:3:40: error: uninitialized 'const MyConst<3>' [-fpermissive]
    3 | template<int N> inline constexpr float MyConst;
      |                            

这可以通过为MyConst提供一个初始定义来解决,例如。

// Use a "sensible default"
template<int N> inline constexpr float MyConst(0.0f);

// Provide a more general definition
template<int N> inline constexpr float MyConst = N*1.1f;

有关标准的相关部分,请参见DCL.Constexpr第1段。

constexpr说明符应仅应用于变量或变量模板的定义或函数或函数模板的声明。consteval说明符只能应用于函数或函数模板的声明。使用constexpr或consteval说明符声明的函数或静态数据成员隐式为内联函数或变量。如果函数或函数模板的任何声明具有constexpr或consteval说明符,那么它的所有声明都应包含相同的说明符。

 类似资料:
  • 实际代码更复杂,但我能够将其简化为这个示例。 在我尝试获取指向MyPackets\u t::type的指针(在main()中取消对foo()的注释调用)之前,一切都正常 此时,为了使应用程序链接,类型需要定义。 我正在努力寻找正确的定义语法。已注释掉模板。。。应该做到这一点。但是,它生成了一个错误“PacketCollection::types的模板参数与原始模板不匹配”。 尝试这样的东西-模板

  • template.defaults.imports 模板通过 $imports 可以访问到模板外部的全局变量与导入的变量。 导入变量 template.defaults.imports.log = console.log; <% $imports.log('hello world') %> 内置变量清单 $data 传入模板的数据 $imports 外部导入的变量以及全局变量 print 字符

  • 我有以下示例类<code>Foo</code>和嵌套类<code<Bar</code<,所有内容都是<code>constexpr</code>: 我想测试调用<code>Foo::DoTheThing</code>返回1: 海湾合作委员会和Clang都在这里抱怨,但MSVC没有 GCC表示: 错误: ,或者如果我将< code>Bar的定义移到< code>Foo之外,我可以让GCC和Clang

  • YDoc 主题的模板是若干的 jsx 组件,以下是各模板文件相对应的功能(按首字母排序): 模板 功能 Content.jsx 文档页内容 Footer.jsx (用户自定义组件) Footer 信息 Head.jsx html 文件中 部分的内容 Header.jsx 顶部导航 Homepage.jsx (用户自定义组件) 文档站首页 Hook.jsx 钩子,用于自定义插件 Icon.jsx f

  • 我试图在编译时使用C11新的constexpr特性来计算这个简单表达式: 但这是Clang一直告诉我的: 奇怪的是,下面的代码编译得很好: 你们知道为什么a/b不是一个常量表达式吗,我如何在编译时计算它? 将Clang编译器与-std=c1y和-stdlib=libc一起使用 [更新] 以下示例导致了原始代码的错误: 而: 没有。

  • 问题内容: 我试图将值放入“标题”模板中,例如标题和导航链接,但无法访问我从包含的模板发送到主模板的变量。 渲染模板: index.html模板: header.html模板: 显然,它不会那样工作。 也许有一种方法可以解析/获取模板并将变量放入其中,而无需将整个头文件放入代码中?然后,我可以将该模板作为变量发送到我的主模板。但这似乎并不是最好的方法。 问题答案: 您可以在调用模板时将上下文传递给