标签: constexpr

有替换X-macros的模板/ constexpr/C++ 11方法吗?

有没有办法用C++ 11功能替换Xmacro习语,最好不要使用预处理器?我认为可以使用元组模板,但我仍然试图弄清楚这些是如何工作的.

c++ templates constexpr c++11

10
推荐指数
1
解决办法
614
查看次数

内部类的奇怪constexpr行为

任何人都可以试着解释一下吗?

template<typename T, size_t S = T::noElems()>
struct C
{
};

struct X
{
    enum E { A, B, C };
    static constexpr size_t noElems() { return C+1; };
};

struct K
{
    C<X> cx; // this DOES compile
};

struct Y
{
    struct Z
    {
        enum E { A, B, C };
        static constexpr size_t noElems() { return C+1; };
    };
    C<Z, Z::C+1> cyz; // this DOES compile

    C<Z> cyz; // <--- this does NOT compile 
};
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11

10
推荐指数
1
解决办法
297
查看次数

constexpr std :: array with static_assert

#include <iostream>
#include <array>

int main(int argc, char **argv) {
    constexpr const std::array<int, 2> arr {{ 0, 1 }};
    constexpr const int arr2[] = { 0, 1};

    static_assert(arr[0] == arr2[0], "asdf");
    static_assert(arr[1] == arr2[1], "asdfasdf");

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

当编译gcc 4.8.24.9.1使用g++ test.cpp --std=c++11,编译成功.当编译clang 3.43.5利用clang++ test.cpp --std=c++11然而,编译失败:

test.cpp:8:16: error: static_assert expression is not an integral constant expression
        static_assert(arr[0] == arr2[0], "asdf");
                      ^~~~~~~~~~~~~~~~~
test.cpp:8:16: note: non-constexpr function 'operator[]' cannot be used …
Run Code Online (Sandbox Code Playgroud)

c++ static-assert constexpr c++11 stdarray

10
推荐指数
1
解决办法
1228
查看次数

C++:为什么这个constexpr不是编译时常量

在下面的C++ 11代码中,对arraySize的最后一次调用会导致编译错误.显然这是因为y是运行时大小的数组,并且不能推导出y的arraySize模板参数N. 我不明白为什么x是一个编译时大小的数组,但y结束了运行时大小.arraySize模板函数直接取自Scott Meyers的"Effective Modern C++"第1项.

#include <cstddef>

template<typename T, std::size_t N>
constexpr std::size_t arraySize(T(&)[N]) noexcept { return N; }

struct S
{
    char c[10];
};

int main()
{
    S s;
    S* ps = &s;

    char x[arraySize(s.c)];
    char y[arraySize(ps->c)]; // why is y a runtime sized array?

    arraySize(x);
    arraySize(y); // error !?

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

templates constexpr c++11

10
推荐指数
1
解决办法
1215
查看次数

为什么constexpr不是所有功能的默认值?

在放宽constexpr的规则之后,似乎这些功能可以在任何地方使用.它们也可以在常量(constexpr)和局部(可变)变量上调用.所以对我来说,它似乎只是编译器的一个提示(如内联).我只是继续在任何地方写它并在编译器抱怨时删除它.因此,如果可以在编译时评估函数,编译器似乎知道所有内容.为什么它不是默认行为,为什么我必须将任何东西标记为constexpr?

c++ constexpr c++14

10
推荐指数
1
解决办法
1036
查看次数

Constexpr lambda默认情况下?

根据n4487和其他c ++ 17引用,将会有新的lambda函数说明符 - constexpr如果存在,则"明确指定函数调用运算符是一个constexpr函数." .我理解lambda中常量表达式的动机.对我来说有趣的是提案的第4点,其中指出:

4)如果constexpr在lambda声明符中省略了说明符,则函数调用运算符(或模板)constexpr是否满足constexpr函数的要求.

这引出了两个问题:

  1. 为什么我们需要constexpr说明符?看起来lambda调用操作符是否将constexpr取决于它"满足constexpr函数的要求"的事实,而不是来自 constexpr说明符的存在.
  2. 如果constexpr默认情况下可以接受lambda,那么为什么不建议其他类型的函数 - 例如全局函数?如果编译器开始处理涵盖需求的所有函数,会产生什么影响constexpr

c++ lambda constexpr c++17

10
推荐指数
1
解决办法
638
查看次数

我应该更喜欢函数中的常量:constexpr const还是enum?

我习惯用定义我的常量enum { my_const = 123; },因为在类中,使用static constexpr需要在类定义之外的一些代码(参见这个问题).但是 - 功能体呢?最近我注意到人们只是constexpr在他们的功能中有变量(const实际上甚至没有打扰他们),我想知道我是不是一个傻瓜谁是我的时代背后

int foo(int x)
{
    enum : int { bar = 456 };
    return x + bar;
}
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是:在函数体中使用枚举而不是constexpr变量有什么好处吗?

c++ enums constexpr c++11

10
推荐指数
1
解决办法
611
查看次数

枚举像计算常数

实际上这个"问题"感觉非常简单.在做一些计算出的图标偏移时,我想出了以下方法:

namespace Icons {

  struct IconSet {
    constexpr IconSet(size_t base_offset) noexcept
      : base_offset_(base_offset), icon(base_offset * 3), iconSmall(icon + 1), iconBig(icon + 2) {
    }
    size_t icon;
    size_t iconSmall;
    size_t iconBig;

    size_t base_offset_;

    constexpr size_t next() const {
      return base_offset_ + 1;
    }
  };


  static constexpr IconSet flower = IconSet(0);
  static constexpr IconSet tree = IconSet(flower.next());
  static constexpr IconSet forest = IconSet(tree.next());
  static constexpr IconSet mountain = IconSet(forest.next());

 }
Run Code Online (Sandbox Code Playgroud)

现在可以编写一个Icons::tree.iconBig例子来获取该图标的计算偏移量.基本上,设计师可以更改图标 - 有时也可以添加/删除 - 但总是按惯例提供整个设置(正常,小和大).

如你所见,这种方法的问题是我必须做这个next()功能并重复使用它 - 正常的枚举不会有这个缺点. …

c++ constexpr c++17

10
推荐指数
1
解决办法
678
查看次数

为什么允许一些非常量表达式作为constexpr逗号运算符的操作数?

考虑一个简单的例子:

int foo() {
    return 3;
}

template <int>
struct Bar {};

int a;

int main() {
    int b;
    //Bar<((void)foo(), 1)> bar1;  //case 1. compilation error as expected
    Bar<((void)a, 2)> bar2;        //case 2. no error (long shot but `a' has a linkage so maybe expected)
    Bar<((void)b, 3)> bar3;        //case 3. no error ? (`b' does not have linkage) 
    (void)bar2;
    (void)bar3;
}
Run Code Online (Sandbox Code Playgroud)

我会说这是一个错误,但最新的[clang][gcc]接受代码所以也许我错过了一些使代码有效的相关标准规则?

c++ comma-operator language-lawyer constexpr c++11

10
推荐指数
1
解决办法
263
查看次数

constexpr映射要使用什么类型?

理想情况下,我想写:

constexpr std:map<std::string, std::string> my_map = 
  {{"key1", "val1"}, {"key2", "val2"}, };
Run Code Online (Sandbox Code Playgroud)

要么

constexpr std:unordered_map<std::string, std::string> my_map =
  {{"key1", "val1"}, {"key2", "val2"}, };
Run Code Online (Sandbox Code Playgroud)

但是都不可能(至少在当前语言是不可能的)

那还有什么选择呢?

例如,我可以做以下事情:

constexpr std::initializer_list< std::pair<const char*, const char *> > my_map = 
  {{"key1", "val1"}, {"key2", "val2"}, };
Run Code Online (Sandbox Code Playgroud)

然后在运行std::map时需要构造一个。我知道我也可以使用inline代替constexpr,但是那时我将无法在编译时使用(也许在开发的后期)。但是,这有点不令人满意(因为我不得不在运行时仅出于查找目的构造映射),我想知道:是否有更好的解决方案?

c++ stdmap constexpr c++17

10
推荐指数
0
解决办法
180
查看次数