标签: constexpr

constexpr(gcc)出错 - 错误:在'{'标记之前,不允许使用括号括起的初始值设定项

struct X {
constexpr static char a1[] = "hello"; // Okay
constexpr static const char* a2[] = {"hello"}; // Error
};

int main(){}
Run Code Online (Sandbox Code Playgroud)

使用gcc编译会出错:

错误:在'{'标记之前,不允许使用括号括起的初始值设定项

这是constexpr的非法使用吗?

编辑

我尝试了3个不同版本的gcc,它在我最新的4.7.0上编译(我刚刚下载它,我使用的是mingw-w64),所以它看起来是一个固定的bug(这个bug的链接会是不过很好!)

4.7.0 20120311(预发行)//好的
4.6.4 20120305(预发布)//错误
4.7.0 20110829(实验性)//错误

c++ constexpr c++11

6
推荐指数
1
解决办法
2152
查看次数

如何让GCC在ROM中放置C++ constexpr?

我为LPC1114编译,这是一个小型ARM(实际上是Cortex)目标.RAM比ROM更受限制.我使用最新的Mentor(CodeBenchLite)GCC编译器(GCC 4.6.3).我有一些我希望在ROM中拥有的常量对象.据我所知,下面代码中的ffx对象最终应该在ROM(代码)中,但它放在DATA中.

class flop {
    public:
       int x;
       constexpr flop( int x ) : x(x){}
};

 extern constexpr flop ffx( 1 );
Run Code Online (Sandbox Code Playgroud)

如何说服编译器预先计算对象并将其放在ROM中?

或者我应该问:

  • 我能以某种方式期望G ++编译器为ffx生成可ROMable数据
  • 如果是这样,我的代码是否正确
  • 如果是这样,支持G ++版本(我使用4.6,也许我需要4.7?)

=======================================

这个bugzilla条目c ++/49673似乎表明我的已知问题,可能已在GCC 4.7中修复.不幸的是,我更喜欢使用内置的Mentor/CodeSourcery,它仍然是4.6.3.所以我想暂时我会遇到这个bug.:(

c++ gcc arm constexpr

6
推荐指数
1
解决办法
1235
查看次数

静态大小的valarray实现

我正在寻找静态大小的std::valarray实现。

我自己可以轻松实现它,但是我需要进行constexpr操作(求和,减法等),而且这样做很无聊/容易出错,所以我在这里问是否有一个流行的实现。

如果我必须自己实现这一点,那么您认为在这种情况下表达式模板值得吗?

c++ constexpr c++11

6
推荐指数
1
解决办法
618
查看次数

clang 3.3和GCC 4.7 const v的constexpr

我刚刚尝试使用clang 3.3和Ubuntu 13.04上的GCC 4.7.3标准库头文件编译相当大的代码.除了一个问题外,一切顺利.这段代码已经在这台机器上编译了标准的Ubuntu clang 3.2软件包,所以我假设这是clang 3.3编译器的一些变化.与使用复杂标头的const和constexpr相关的问题.特别是复杂类型具有以下代码块

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // DR 387. std::complex over-encapsulated.
      constexpr double
      real() { return __real__ _M_value; }

      constexpr double
      imag() { return __imag__ _M_value; }
#else
      double&
      real() { return __real__ _M_value; }

      const double&
      real() const { return __real__ _M_value; }

      double&
      imag() { return __imag__ _M_value; }

      const double&
      imag() const { return __imag__ _M_value; }
#endif
Run Code Online (Sandbox Code Playgroud)

在我的编译中,我输入第一个代码块,因此编译器可以看到

constexpr double real() { return __real__ _M_value; }
Run Code Online (Sandbox Code Playgroud)

这导致clang产生错误,实际成员函数不是const,具有以下内容

/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/complex:1212:7: 
note: candidate function …
Run Code Online (Sandbox Code Playgroud)

c++ const constexpr c++11 c++14

6
推荐指数
1
解决办法
1213
查看次数

无法创建字符串文字类型

我想创建一个我可以用作模板参数的字符串文字.它将编译器抛入某种无限循环.有什么问题并修复?

template <char...> struct slit { };

template <typename ...A>
constexpr auto make_slit(char const* const s, A const ...args)
{
  return *s ? make_slit(s + 1, *s, args...) : slit<args...>();
}

int main()
{
  auto const tmp_(make_slit("slit"));

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

强制性错误(带clang++ -std=c++1y):

t.cpp:4:16: fatal error: recursive template instantiation exceeded maximum depth of 256
constexpr auto make_slit(char const* const s, A const ...args)
               ^
t.cpp:6:15: note: in instantiation of function template specialization 'make_slit<char, char, char, char, char, char, char, …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++14

6
推荐指数
1
解决办法
684
查看次数

用户定义的文字到MPL序列:这是合法的吗?

能够将传递给文字运算符的字符串转换为MPL序列将非常有用,因为我们可以根据字符串的内容控制代码生成.以前,我认为这是不可能的,因为constexpr函数的参数不被视为函数体内的常量表达式.但是,我提出了在Clang 3.4.2和GCC 4.8.2下编译的以下解决方法:

#include <cstdint>
#include <iostream>
#include <typeinfo>

struct string
{
    const uintmax_t m_str[64];
    const size_t m_length;

    template <class... Ts>
    constexpr string(const Ts... ts) :
    m_str{(uintmax_t)ts...}, m_length{sizeof...(Ts)} {}

    constexpr size_t size() const { return m_length; }
    constexpr size_t length() const { return m_length; }
    constexpr uintmax_t operator[](size_t n) const { return m_str[n]; }
};

template <uintmax_t... Ts> struct sequence {};

constexpr auto
operator"" _tag(const char* str, size_t n)
{
    return n == 0 ? string{} :
           n == 1 …
Run Code Online (Sandbox Code Playgroud)

c++ template-meta-programming user-defined-literals constexpr c++14

6
推荐指数
1
解决办法
166
查看次数

获取常量char数组的字符串长度函数(strlen)不是常量表达式

让我们直接看一下简化的代码(编译:GCC 6.3.0)

#include<iostream>
#include<cstring>

using namespace std;

int main(int arga, char* argv[]) {

    const char cs[] = "Hello";//define a constant c-style string 
    constexpr size_t newSize = strlen(cs) + strlen(" ");//Error

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器产生错误: strlen(((const char*)(&cs)))不是常量表达式

但是,当我将c字符串定义移动到全局范围时,问题就会消失.

.... 
const char cs[] = "Hello";

int main(int arga, char* argv[]) {
    constexpr size_t newSize = strlen(cs) + strlen(" ")//No Error
 ....
}
Run Code Online (Sandbox Code Playgroud)

有人能解释发生了什么吗?为什么strlen()将全局定义的常量c-string视为常量表达式,而不是堆栈中的那个?

c++ arrays constexpr

6
推荐指数
1
解决办法
472
查看次数

当用作函数参数时,C++"遗忘"该变量是constexpr

我有以下代码,我厌倦了编译器无法看到作为函数的参数传递的变量是constexpr的事实,所以我必须使用arity 0函数而不是1参数函数.

我知道这不是编译器错误,但我想知道是否有成语可以解决这个问题.

#include <array>
#include <iostream>

static constexpr std::array<int, 5> arr{11, 22, 33, 44, 55};

template <typename C, typename P, typename Y>
static constexpr void copy_if(const C& rng, P p, Y yi3ld) {
    for (const auto& elem: rng) {
        if (p(elem)){
            yi3ld(elem);
        }
    }
}

// template<std::size_t N>
static constexpr auto get_evens(/* const std::array<int, N>& arr */) {
    constexpr auto is_even = [](const int i) constexpr {return i % 2 == 0;};
    constexpr int cnt = [/* &arr, */&is_even]() …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++17

6
推荐指数
2
解决办法
426
查看次数

如何在编译时从两个索引序列创建数组

扰流器 -这是一个自我回答的问题)让我们假设我有两个索引序列,例如using i1 = std::index_sequence<1, 3, 5, 7>;using i2 = std::index_sequence<2, 4, 6, 8>;

我想创建一个数组(在编译时),该数组中将依次包含8个元素:1, 2, 3, 4, 5, 6, 7, 8,以便以下代码可以工作(例如,在全局范围内):

std::array<int, 8> arr = make_array(i1{}, i2{});
Run Code Online (Sandbox Code Playgroud)

注意:如果我只想要一个序列,则解决方案很简单:

template<size_t... Ix>
constexpr auto make_arr(std::index_sequence<Ix...> )
    return std::array{Ix...};
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我需要连接两个序列,那并不是那么简单,例如,这是行不通的:

template<size_t... Ix1, size_t... Ix2>
constexpr auto make_arr(std::index_sequence<Ix1...>, std::index_sequence<Ix2...>)
    return std::array{(Ix1, Ix2)...};
}
Run Code Online (Sandbox Code Playgroud)

(上面的代码将使用第二个序列中的值填充数组)。

另一个可能的解决方案是使用constexpr函数,该函数首先定义一个具有默认值的数组,然后将索引序列中的值复制到该数组中,但是虽然该方法适用于ints,但不适用于某些更为复杂的类型,这些类型不是默认的-可构造的(显然,它们不是索引序列的一部分,但可以是其他东西)。

是否有不需要循环和默认构造值的解决方案?任何可用的C ++标准都是公平的游戏。

c++ template-meta-programming variadic-templates constexpr c++17

6
推荐指数
1
解决办法
437
查看次数

是否可以声明constexpr指针而不是指向constexpr的指针?

正确吗

constexpr int* p = nullptr;
Run Code Online (Sandbox Code Playgroud)

声明constexpr指针(而不是constexpr int指针)?

这个定义

int* constexpr p = nullptr;
Run Code Online (Sandbox Code Playgroud)

给出编译错误。

c++ constexpr c++11

6
推荐指数
1
解决办法
182
查看次数