标签: constexpr

如何在constexpr函数中使用临时变量?

这是我想要做的简化版本.

constexpr float f(float a, float b){
    constexpr float temp = a+b;
    return temp*temp*temp;
}
Run Code Online (Sandbox Code Playgroud)

在我的版本中,a + b更复杂,所以我不想剪切和粘贴三次.使用3*(a + b)也不是实际功能的有效解决方案.我试图保持与语法相关的问题,而不是代数.我可以通过将+ b移动到它自己的constexpr函数来实现它,但我宁愿不用其他无用的函数来污染命名空间.

c++ constexpr

5
推荐指数
2
解决办法
856
查看次数

Constexpr类模板成员函数与推导的void返回类型?

考虑以下简单的类X和类模板Y<T>,每个模板定义四个constexpr成员,其中三个具有推导的返回类型(新的C++ 1y特性),另外三个子集使用另一个新的C++ 1y特性:轻松constexpr现在也可以有副作用和void返回类型的功能.

下面是一个与这些功能相互作用的小实验:

#include <type_traits>
#include <utility>

struct X
{
    constexpr void fun() {}             // OK
    constexpr auto gun() {}             // OK
              auto hun() {}             // OK
    constexpr auto iun() { return 0; }  // OK
};

template<class T>
struct Y
{
    constexpr void fun() {}             // OK
  //constexpr auto gun() {}             // ERROR, why?
              auto hun() {}             // OK
    constexpr auto iun() { return 0; }  // OK …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11 return-type-deduction c++14

5
推荐指数
1
解决办法
890
查看次数

Constexpr decltype

我最近在这里问了一个问题(用SFINAE检测实例方法constexpr),我试图在编译时进行一些constexpr检测.最后,我发现可以利用noexcept这个来做:任何常量表达式也是如此noexcept.所以我把以下机器放在一起:

template <class T>
constexpr int maybe_noexcept(T && t) { return 0; }
...
constexpr bool b = noexcept(maybe_noexcept(int{}));
Run Code Online (Sandbox Code Playgroud)

这是正常的,b正如您所期望的那样,因为零初始化int是一个常量表达式.它应该正确地产生零(如果我改为int其他适当的类型).

接下来,我想检查某些东西是否可constexpr移动构造.所以我这样做了:

constexpr bool b = noexcept(maybe_noexcept(int(int{})));
Run Code Online (Sandbox Code Playgroud)

而且,这适用于int或用户定义的类型.但是,这会检查该类型是否包含constexpr默认构造函数和constexpr移动构造函数.所以,为了解决这个问题,我尝试改为declval:

constexpr bool b = noexcept(maybe_noexcept(int(declval<int>())));
Run Code Online (Sandbox Code Playgroud)

这导致在bgcc 5.3.0 中为false(不能使用任何一个clang,因为clang不能正确地生成常量表达式noexcept).没问题,我说,一定是因为declval(有趣的是)没有标记constexpr.所以我写了自己的天真版本:

template <class T>
constexpr T&& constexpr_declval() noexcept;
Run Code Online (Sandbox Code Playgroud)

是的,与标准库的工作方式相比,这是天真的,因为它会阻塞虚空和可能的其他东西,但它现在很好.所以我再试一次:

constexpr bool b = noexcept(maybe_noexcept(int(constexpr_declval<int>())));
Run Code Online (Sandbox Code Playgroud)

这仍然不起作用,b总是假的.为什么这不被视为常数表达式?这是一个编译器错误,还是我不了解基本原理constexpr?似乎在constexpr和未评估的上下文之间存在一些奇怪的交互.

c++ template-meta-programming constexpr c++11

5
推荐指数
1
解决办法
839
查看次数

constexpr计算量的实际限制

作为一个实验,我只是将一些代码放在一起,以便std::array<uint32_t, 256>在编译时生成.表内容本身是一个相当典型的CRC查找表 - 关于唯一新的事情是使用constexpr函数来计算条目而不是将自动生成的魔术表直接放在源代码中.

无论如何,这个练习让我很好奇:编译器constexpr在编译时评估函数或变量定义的计算量是否会有任何实际限制?例如,像gcc的-ftemplate-depth参数一样,对模板元编程评估的数量创建实际限制.(我也想知道参数包的长度是否存在实际限制 - 这将限制std::array使用std::integer_sequence中间对象创建的编译时的大小.)

c++ limits constexpr c++11 c++14

5
推荐指数
1
解决办法
432
查看次数

在某些情况下允许从constexpr调用非constexpr函数

来自这个问题: 如何构建自定义宏,用作constexpr(如assert)时,其行为会有所不同?

我想知道如果有条件的话为什么可以调用非constexpr函数。

void bla( )
{
    std::cout << "bla called!" << std::endl;
}

constexpr bool check(bool condition)
{
    //bla(); // can not directly be called -> not constexpr! 
    condition ? void (0) : bla(); // compiles and runs even if condition is true or false!

    // if condition is const, it did not compile because it
    // directly force execution of non constexpr function
    true ? void(0): bla(); // also that compiles!, ok, directly evaluated
    //true ? bla(): void(0); …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++14

5
推荐指数
1
解决办法
3121
查看次数

无法编译包含"if constexpr"的函数模板实例化

对于模糊的标题感到抱歉,但我无法想出一个更好的标题.

我写了一个扁平化容器的函数:

template <typename Container, typename OutIt>
void flatten(const Container& container, OutIt res)
{
    if constexpr (std::is_convertible_v<typename Container::value_type, typename std::iterator_traits<OutIt>::value_type>)
    {
        for (const auto& value : container)
        {
            *res = value;
            ++res;
        }
    }
    else
    {
        for (const auto& subContainer : container)
            flatten(subContainer, res);
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望它像以下一样使用:

vector<vector<int>> test = {{1}, {2, 3, 4}, {5, 6}, {7}};
vector<int> res;
flatten(test, std::back_inserter(res));
Run Code Online (Sandbox Code Playgroud)

这应该基本上是从复制所有嵌套值testres,这样res == { 1, 2, 3, 4, 5, 6, 7 }.

但是,如果我想编译代码,编译器会抛出一些错误,基本上说,else …

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

5
推荐指数
1
解决办法
80
查看次数

constexpr variadic模板和解压缩std :: array

我想编写一个constexpr模板函数来置换作为参数传入的数组元素.所以我想出了这样的事情:

template <typename T, std::size_t N, typename... Ts>
constexpr std::array<T, N> permute(const std::array<T, N>& arr, const std::array<int, N>& permutation, Ts&&... processed)
{
    return (sizeof...(Ts) == N) ?
        std::array<T, N>{ std::forward<Ts>(processed)... } :
        permute(arr, permutation, std::forward<Ts>(processed)..., arr[permutation[sizeof...(Ts)]]);
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

constexpr std::array<int, 3> arr{ 1, 2, 3 };
constexpr std::array<int, 3> permutation{ 2, 1, 0 };
constexpr auto result = permute(arr, permutation); //result should contain { 3, 2, 1 }
Run Code Online (Sandbox Code Playgroud)

问题是上面的代码没有编译.出于某种原因,g ++ 6.4尝试在"已处理"模板参数包下隐藏4个或更多参数来实例化置换模板.你能帮我纠正我的代码并让它编译吗?

完整代码

c++ variadic-templates constexpr c++11

5
推荐指数
1
解决办法
671
查看次数

标题中的constexpr数组

我在头文件中有以下代码,它包含在2个不同的cpp文件中:

constexpr int array[] = { 11, 12, 13, 14, 15 };
inline const int* find(int id)
{
    auto it = std::find(std::begin(array), std::end(array), id);
    return it != std::end(array) ? &*it : nullptr;
}
Run Code Online (Sandbox Code Playgroud)

然后我调用find(13)每个cpp文件.将两个指针返回find()指向内存中的同一地址吗?

我问的原因是因为我的项目中有类似的代码,有时它可以工作,有时则不然.我假设两个指针都指向同一个位置,但我并没有真正有这个假设的基础:)

c++ pointers constexpr

5
推荐指数
1
解决办法
775
查看次数

如果在C++ 14或更高版本上,非const的成员函数应该只是constexpr

在C++ 11中,成员函数上的constexpr意味着const.这在C++ 14中有所改变.

我有一些代码,其成员函数应该是constexpr,但不能是const,所以如果用std c ++ 14或更高版本编译,我希望它是constexpr.一种方法是:

class Foo {
#if _cplusplus >= 201402L
    constexpr
#endif
    int baz(const Bar& bar);
};
Run Code Online (Sandbox Code Playgroud)

是否有更好的方式表达这一点,最好没有预处理器?

c++ member-functions c-preprocessor constexpr c++14

5
推荐指数
1
解决办法
139
查看次数

constexpr结构成员初始化

此代码编译:

struct Info
{
    constexpr Info(bool val) : counted(false), value(unsigned(val)) {}
    constexpr Info(unsigned val) : counted(true), value(val) {}

    bool counted;
    unsigned value;
};

constexpr const auto data = std::array{
    Info{true}, Info{42u}
};

struct Foo
{
    constexpr static inline const auto data = std::array{
        Info{true}, Info{42u}
    };
};
Run Code Online (Sandbox Code Playgroud)

此代码不会:

struct Foo
{
    struct Info
    {
        constexpr Info(bool val) : counted(false), value(unsigned(val)) {}
        constexpr Info(unsigned val) : counted(true), value(val) {}

        bool counted;
        unsigned value;
    };

    constexpr static inline const auto data = …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++17

5
推荐指数
1
解决办法
422
查看次数