标签: constexpr

如何检查模板参数是否为2的幂?

我想创建一个静态分配2 ^ N字节数组的结构,但我不希望此结构的用户将此大小指定为指数.例:

my_stupid_array<char, 32> a1; // I want this!
my_stupid_array<char, 5> a2; // And not this...
Run Code Online (Sandbox Code Playgroud)

如何检查此模板参数是否为2的幂警告用户有关于此的好消息?

我已经能够通过一个简单的模板检查这个:

template<int N>
struct is_power_of_two {
    enum {val = (N >= 1) & !(N & (N - 1))};
};
Run Code Online (Sandbox Code Playgroud)

但是,我无法通过合理的消息警告用户.有任何想法吗?

编辑

修复了模棱两可的例子.

编辑

1确实是2的幂.修好了!:)

编辑

使用BOOST_STATIC_ASSERT,我收到此代码与GCC的编译错误:

template<int N>
struct is_power_of_two {
    enum {val = (N >= 1) & !(N & (N - 1))};
    BOOST_STATIC_ASSERT(val);
};
Run Code Online (Sandbox Code Playgroud)

错误

..\main.cpp:29:1: error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>' 
Run Code Online (Sandbox Code Playgroud)

http://ideone.com/cMfEf

编辑 …

c++ templates static-assert constexpr c++11

16
推荐指数
3
解决办法
4170
查看次数

可以在C++ 14 constexpr函数中使用for循环实例化模板吗?

我一直在乱搞SVN构建的clang来试验放松的规则constexpr.我之前无法确定的一件事是,是否可以在constexpr函数中在编译时循环遍历元组内的元素.

因为我没有要测试的符合C++ 14的标准库,所以我准备了以下等效测试:

template<int N>
constexpr int foo() {
  return N;
}

constexpr int getSum() {
  auto sum = 0;
  for (auto i = 0; i < 10; ++i) {
    sum += foo<i>();
  }
  return sum;
}

constexpr auto sum = getSum();
Run Code Online (Sandbox Code Playgroud)

这里有趣的部分是foo<i>().在非constexpr函数中,我希望它无法编译,因为您根本无法使用运行时int来生成模板的编译时实例化.constexpr但是,因为这是一个功能,我怀疑这是否可行.特别是,该值在编译时是已知的,即使它允许变异.

我知道以下代码编译:

constexpr auto nValue = 2;
foo<nValue>();
Run Code Online (Sandbox Code Playgroud)

在SVN clang中,我的第一个例子没有:

test2.cpp:19:12: error: no matching function for call to 'foo'
    sum += foo();
           ^~~~~~
test2.cpp:11:15: note: candidate template ignored: invalid explicitly-specified …

c++ constexpr c++14

16
推荐指数
1
解决办法
3231
查看次数

宣布constexpr专业化为朋友

我有一个模板化的类A和一个f返回A对象的模板化函数.我想f<T>成为朋友,现在A<T>仍然是constexpr

template <typename T>
class A;

template <typename T>
constexpr A<T> f();

//f<T> is a friend of A<T>

template <typename T>
class A {
  friend /* constexpr? */ A f<T>();
  constexpr A() {}
};

template <typename T>
constexpr A<T> f() { return {}; }

int main() {
  constexpr auto a  = f<void>();
}
Run Code Online (Sandbox Code Playgroud)

我不能让clang和gcc同意这里的内容.如果我没有constexpr输入好友声明,gcc工作正常但clang不会编译它,错误的:

main.cpp:18:18: error: constexpr variable 'a' must be initialized by a constant expression
  constexpr …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang constexpr c++11

16
推荐指数
1
解决办法
398
查看次数

如何确保constexpr函数从未在运行时调用?

假设您有一个为您的应用程序生成一些安全性令牌的函数,例如一些哈希盐,或者可能是对称或非对称密钥.

现在假设您在C++中将此函数作为constexpr,并根据某些信息(例如,构建号,时间戳,其他内容)为构建生成密钥.

你是一个勤奋的程序员,确保并以适当的方式调用它,以确保它只在编译时被调用,因此死剥离器从最终的可执行文件中删除代码.

但是,您无法确定其他人是否会以不安全的方式调用它,或者编译器可能不会删除该功能,然后您的安全令牌算法将成为公共知识,使其成为公共知识更容易让攻击者猜测未来的令牌.

或者,除了安全性之外,假设该函数需要很长时间才能执行,并且您希望确保它在运行时期间永远不会发生,并且会给最终用户带来糟糕的用户体验.

有没有办法确保在运行时永远不会调用constexpr函数?或者,在运行时抛出一个断言或类似的东西就可以了,但不像编译错误那样明显.

我听说有一些方法涉及抛出一个不存在的异常类型,所以如果constexpr函数没有被删除,你会得到一个链接器错误,但是听说这只适用于某些编译器.

远程相关的问题:强制constexpr在编译时进行评估

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

16
推荐指数
4
解决办法
2033
查看次数

静态constexpr:为什么需要模板化?

我有两个结构ab:

struct a {
    static constexpr int f() {
        return 1;
    }

    static constexpr int c = f();
};

template<int I>
struct b {
    static constexpr int f() {
        return I;
    }

    static constexpr int c = f();
};
Run Code Online (Sandbox Code Playgroud)

a显然不起作用,因为f这里没有定义.但为什么地狱b有效呢?

c++ constexpr c++14

16
推荐指数
1
解决办法
242
查看次数

C++ 17 constexpr字符串解析

对不起,这将是一个很长的帖子,但我觉得你需要所有的代码来看看发生了什么.


所以,我一直在尝试将编译时字符串转换为数据结构解析器.想象一下像正则表达式这样的东西,其中字符串在编译时被"编译"成数据结构但在运行时执行(只要输入字符串当然是常量).但是我遇到了一个我不太明白错误的问题:

基本上,我的设计是一个2遍解析器:

  • 传递1:确定输入字符串中有多少"操作码"
  • 传递2:返回一个大小由Pass 1确定的数组,并填入"opcodes"

这是事情的样子:

// a class to wrap string constants
class constexpr_string {
public:
    template <size_t N>
    constexpr constexpr_string(const char (&s)[N]) : string_(s), size_(N - 1) {}
public:
    constexpr size_t size() const     { return size_; }
    constexpr size_t capacity() const { return size(); }
    constexpr size_t empty() const    { return size() != 0; }
public:
    constexpr char operator[](size_t n) const { return string_[n]; }
private:
    const char *string_;
    size_t      size_;
};

// would have loved to …
Run Code Online (Sandbox Code Playgroud)

c++ parsing constexpr c++17

16
推荐指数
1
解决办法
1848
查看次数

任何用constexpr string_view替换全局const char []的陷阱吗?

我们的团队正在使用具有10多年历史的C ++代码库,并且最近切换到了C ++ 17编译器。因此,我们正在寻找使代码现代化的方法。在YouTube的一次会议演讲中,我听到了用替换const char*全局字符串的建议constexpr string_view

由于我们的代码中有很多这样的const char*全局字符串常量,因此我想问一下是否需要了解一些陷阱或潜在问题?

c++ constexpr string-view c++17

16
推荐指数
1
解决办法
345
查看次数

为什么启用未定义的行为清理会干扰优化?

考虑以下代码:

#include <string_view>

constexpr std::string_view f() { return "hello"; }

static constexpr std::string_view g() {
    auto x = f();
    return x.substr(1, 3);
}

int foo() { return g().length(); }
Run Code Online (Sandbox Code Playgroud)

如果我用 GCC 10.2 和 flags 编译它--std=c++17 -O1,我会得到:

foo():
        mov     eax, 3
        ret
Run Code Online (Sandbox Code Playgroud)

此外,据我所知,这段代码没有任何未定义的行为问题。

但是 - 如果我添加 flag -fsanitize=undefined,编译结果是:

.LC0:
        .string "hello"
foo():
        sub     rsp, 104
        mov     QWORD PTR [rsp+80], 5
        mov     QWORD PTR [rsp+16], 5
        mov     QWORD PTR [rsp+24], OFFSET FLAT:.LC0
        mov     QWORD PTR [rsp+8], 3
        mov     QWORD …
Run Code Online (Sandbox Code Playgroud)

c++ gcc compiler-optimization constexpr ubsan

16
推荐指数
2
解决办法
603
查看次数

`constexpr` 和 `#define` 之间的区别

所以我读了关于constexpr 和 const 之间有什么区别的有趣答案,但我很好奇 #define 和 constexpr 之间有什么区别?我觉得 constexpr 只是一个可以选择类型的#define。

c++ macros constexpr

16
推荐指数
2
解决办法
2万
查看次数

`constexpr` 函数可以在 C++ 中前向声明吗?

我可以constexpr在给出定义之前在 C++ 中声明一个函数吗?

考虑一个例子:

constexpr int foo(int);
constexpr int bar() { return foo(42); }
constexpr int foo(int) { return 1; }

static_assert(bar() == 1);
Run Code Online (Sandbox Code Playgroud)

实际上所有编译器都支持,demo:https : //gcc.godbolt.org/z/o4PThejso

但是如果foo在模板中转换函数:

constexpr int foo(auto);
constexpr int bar() { return foo(42); }
constexpr int foo(auto) { return 1; }

static_assert(bar() == 1);
Run Code Online (Sandbox Code Playgroud)

然后 Clang 拒绝接受它,说https://gcc.godbolt.org/z/EG7cG9KTM

<source>:5:15: error: static_assert expression is not an integral constant expression
static_assert(bar() == 1);
              ^~~~~~~~~~
<source>:2:30: note: undefined function 'foo<int>' cannot be used …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer constexpr

16
推荐指数
1
解决办法
441
查看次数