首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果表达式为static_assert,则为

如果表达式为static_assert,则为
EN

Stack Overflow用户
提问于 2016-05-19 10:29:47
回答 2查看 2.1K关注 0票数 24

我想创建一个类模板

代码语言:javascript
运行
复制
template <class T>
class X {
  // here I'll use T::value (among other things)
};

T::value通常是一个稳定的静态变量,但并不总是这样。T::value必须具有积极的价值,所以我希望在编译过程中尽可能地让人们知道这一点。

如果T::value一直是治安官,我会添加static_assert

代码语言:javascript
运行
复制
static_assert(T::value > 0, "need positive number");

是否可以仅在当static_assert是T::value的情况下添加此T::value

EN

回答 2

Stack Overflow用户

发布于 2016-05-19 10:42:56

这在clang++上适用于我:

代码语言:javascript
运行
复制
#include <type_traits>

// The default case, returns true if the value is not constant.
template <typename T, typename = void>
struct IsNonConstantOrPositive {
    static const bool value = true;
};

// The `constexpr` case. We check if we can evaluate `T::value == 0` which can only
// be evaluated at compile-time if `T::value` is constant. The whole `enable_if` thing
// is to provide a substitution to ensure SFINAE.
template <typename T>
struct IsNonConstantOrPositive<T, typename std::enable_if<T::value==0||true>::type> {
    static const bool value = T::value > 0;
};

template <typename T>
struct X {
    static_assert(IsNonConstantOrPositive<T>::value, "T::value should be positive");
};

示例:

代码语言:javascript
运行
复制
struct A {  // const > 0, should succeed
    static const int value = 123;
};

struct B {  // const <= 0, should fail
    static const int value = -1234;
};

struct C {   // non-const, should succeed
    static int value;
};

int main() {
    X<A> a;     // ok
    //X<B> b;   // error
    X<C> c;     // ok
}
票数 4
EN

Stack Overflow用户

发布于 2016-05-20 06:46:56

我认为最好对变量的const(expr)-ness进行测试,以便使用如下方式:

代码语言:javascript
运行
复制
struct T {
    ...
    static_assert(!IS_CONSTANT_VAR(value) || value > 0, "trouble is afoot");
};

下面的实现使用了类似于kennytm的解决方案的策略,即在非常量引用上失败。它在Clang和GCC中工作。

代码语言:javascript
运行
复制
#include <type_traits> // enable_if

template<typename T, T& var, typename = void> struct is_constant_var_impl {
    static constexpr bool value = false;
};
template<typename T, T& var>
struct is_constant_var_impl <T, var, typename std::enable_if<(double)var == (double)var>::type> {
    // (double) cast above to thwart GCC's agressive constant folding;
    // perhaps could be removed with a bit more finesse
    static constexpr bool value = true;
};
#define IS_CONSTANT_VAR(...) (is_constant_var_impl<decltype(__VA_ARGS__), (__VA_ARGS__)>::value)

优点

  • 模板可以在不同的类或静态成员名称之间重用。
  • static_assert中不言自明的代码

缺点

  • 在MSVC中不工作。
  • (也许?)使用C++14
  • 毛利率
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37320548

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档