标签: constexpr

constexpr数组和std :: initializer_list

我试图编写一个可以像这样使用的编译时valarray:

constexpr array<double> a = { 1.0, 2.1, 3.2, 4.3, 5.4, 6.5 };

static_assert(a[0] == 1.0, "");
static_assert(a[3] == 4.3, "");

static_assert(a.size() == 6, "");
Run Code Online (Sandbox Code Playgroud)

我设法用以下实现来做它并且它工作正常(使用GCC 4.7):

#include <initializer_list>

template<typename T>
struct array
{
    private:

        const std::size_t _size;
        const T* _data;

    public:

        constexpr array(std::initializer_list<T> values):
            _size(values.size()),
            _data(values.begin())
        {}

        constexpr auto operator[](std::size_t n)
            -> T
        {
            return _data[n]
        }

        constexpr auto size() const
            -> std::size_t;
        {
            return _size;
        }
};
Run Code Online (Sandbox Code Playgroud)

虽然它对我来说很好,但我不确定它的行为,std::initializer_list并且可能会使用一些未定义的行为.

constexpr对于std::initializer_list构造函数,begin并且size很好,即使它不是严格来说C++ …

c++ compile-time initializer-list constexpr c++11

4
推荐指数
1
解决办法
3794
查看次数

S不是字面型吗?

此代码不在Coliru中编译,尽管它似乎符合iso§5.19p2第9个子弹点和iso§3.9p10,即,S是文字类型,因此,S a(1);应该被视为常量表达式.特别是,iso§3.9p10项目符号第3点没有说明有关联合成员的任何内容.

#include <iostream>

struct S
{
    int i;
    float x;

    constexpr S(int j) : i{j} {}
};    

int main()
{
    constexpr S a(1);
}
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11

4
推荐指数
1
解决办法
219
查看次数

删除constexpr会更改gcc上数组的值

constexpr std::array我写道,当试图回答问题并创建一个问题时

// Own implementation as std::array::operator[] is not constexpr :/
template <typename T, std::size_t N>
struct array
{
    constexpr T& operator[] (std::size_t index) { return data[index];}
    constexpr const T& operator[] (std::size_t index) const { return data[index];}

    constexpr std::size_t size() const { return N; }

    T data[N];
};

constexpr array<std::size_t, 1001u> make_bottle_count()
{
    array<std::size_t, 1001u> a = {{0, 1, 2, 3, 4, 1, 2, 1, 2, 3, 1}};
    for (int i = 11; i != a.size(); ++i) {
        a[i] …
Run Code Online (Sandbox Code Playgroud)

c++ compiler-bug constexpr c++14

4
推荐指数
1
解决办法
170
查看次数

使用constexpr auto/char-array变量观察到不同的行为

跟进这个问题有一个constexpr静态字符串会给出一个链接器错误

在这个问题中,这段代码无法编译:

#include <iostream>

struct Test { static constexpr char text[] = "Text"; };

int main()
{
    std::cout << Test::text << std::endl; // error: undefined reference to `Test::text'
}
Run Code Online (Sandbox Code Playgroud)

从评论中,这段代码能够编译:

#include <iostream>

struct Test { static constexpr auto text = "Text"; };

int main()
{
    std::cout << Test::text << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么auto版本可以工作,但版本的数组char没有?

能不能指出标准中的声明允许第二个版本而不允许第一个版本?

我看了一下constexpr静态成员变量的奇怪行为,但它似乎是另一个问题.

c++ language-lawyer constexpr auto c++11

4
推荐指数
1
解决办法
319
查看次数

在编译时计算积分base-2对数的正确方法是什么?

我有一些积极的恒定值来自不同的库而不是我的,称之为the_val.现在,我想log_of_the_val成为楼层(log_2(the_val)) - 不是用C++代码说话 - 我当然希望在编译时发生这种情况.

现在,使用gcc,我可以做类似的事情

decltype(the_val) log_of_the_val = sizeof(the_val) * CHAR_BIT - __builtin_clz(the_val) - 1;
Run Code Online (Sandbox Code Playgroud)

我觉得这应该有用(长度 - 标题零的数量).否则,我可以自己实现一个constexpr函数,但我敢打赌,我可以在编译时使用其他更简单,更便携的东西.......问题是,那会是什么?

logarithm constants idiomatic constexpr c++11

4
推荐指数
1
解决办法
460
查看次数

CRTP编译错误

以下内容将使用GCC 5.2进行编译,但不能使用Visual Studio 2015进行编译.

template <typename Derived>
struct CRTP {
    static constexpr int num = Derived::value + 1;
};

struct A : CRTP<A> {
    static constexpr int value = 5;
};
Run Code Online (Sandbox Code Playgroud)

它抱怨说A没有名字的成员value.如何修复代码以便在两个编译器上编译?或者完全是非法的?

c++ templates crtp constexpr c++11

4
推荐指数
1
解决办法
196
查看次数

每当使用constexpr指定调用的函数时,将委托方法声明为constexpr

请考虑以下课程

template<class T>
class foo
{
public:
    auto bar() { return m_t.bar(); }

private:
    T m_t;
};
Run Code Online (Sandbox Code Playgroud)

如果我们想foo<T>::bar在非投掷时T::bar不投掷,我们可以将其声明更改为

auto bar() noexcept(noexcept(m_t.bar())) { return m_t.bar(); }
Run Code Online (Sandbox Code Playgroud)

但是我们能做什么,如果我们想要foo<T>::bar指定constexpr何时T::bar指定constexpr

我们可以写

constexpr auto bar() noexcept(noexcept(m_t.bar())) { return m_t.bar(); }
Run Code Online (Sandbox Code Playgroud)

它会在两种情况下都有效吗?我用clang 3.7(C++ 17)测试了这个,似乎是这种情况,但我不确定编译器是否在这里正常工作.

c++ templates constexpr c++14 c++17

4
推荐指数
1
解决办法
59
查看次数

constexpr中的"整数常量溢出"警告

我正在尝试在编译时找到一个constexpr兼容的哈希函数用于散列字符串.字符串的数量非常小(<10)并且我对碰撞进行了单独检查,因此算法可能远非完美.我在互联网上找到了以下版本的FNV1A:

static constexpr unsigned int Fnv1aBasis = 0x811C9DC5;
static constexpr unsigned int Fnv1aPrime = 0x01000193;

constexpr unsigned int hashFnv1a(const char *s, unsigned int h = Fnv1aBasis)
{
    return !*s ? h : hashFnv1a(s + 1, (h ^ *s) * Fnv1aPrime);
}
Run Code Online (Sandbox Code Playgroud)

但是当我在MSVS 2015中编译它时,我得到以下警告:

warning C4307: '*': integral constant overflow
Run Code Online (Sandbox Code Playgroud)

由于函数中只有一个乘法我会假设警告来自(h ^ *s) * Fnv1aPrime.这是有道理的,因为乘以0x811C9DC5(Fnv1aBasis)几乎任何东西都会使32位整数溢出.

有什么方法可以解决这个问题吗?我已经尝试了几个其他constexpr函数,我发现它们用于散列字符串,但它们都有相同的问题.

c++ constexpr c++11 visual-studio-2015

4
推荐指数
2
解决办法
2197
查看次数

有条件的constexpr成员函数

假设我有一个模板类

template <typename T>
class foo {
    T m;

    decltype(auto) f() { return m.f(); }
};
Run Code Online (Sandbox Code Playgroud)

foo:f()如果T::f()是constexpr,我怎样才能给constexpr说明符?

c++ templates constexpr c++14

4
推荐指数
1
解决办法
516
查看次数

初始化一个constexpr std :: arrays对

在C ++ 14,我怎么初始化全局constexpr std::arraystd::pair包含文本字符串?以下内容不起作用:

#include <array>

constexpr std::array<std::pair<int, const char[]>, 3> strings = {
  {0, "Int"},
  {1, "Float"},
  {2, "Bool"}};

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

c++ arrays constexpr c++14

4
推荐指数
1
解决办法
502
查看次数