标签: static-assert

const变量的静态断言?

静态断言非常便于在编译时检查事物.一个简单的静态断言习惯用法如下:

template<bool> struct StaticAssert;
template<> struct StaticAssert<true> {};

#define STATIC_ASSERT(condition) do { StaticAssert<(condition)>(); } while(0)
Run Code Online (Sandbox Code Playgroud)

这对于像这样的东西很有用

STATIC_ASSERT(sizeof(float) == 4)
Run Code Online (Sandbox Code Playgroud)

和:

#define THIS_LIMIT (1000)
...
STATIC_ASSERT(THIS_LIMIT > OTHER_LIMIT);
Run Code Online (Sandbox Code Playgroud)

但是使用#define不是定义常量的"C++"方式.C++会让你使用匿名命名空间:

namespace {
    const int THIS_LIMIT = 1000;
}
Run Code Online (Sandbox Code Playgroud)

甚至:

static const int THIS_LIMIT = 1000;
Run Code Online (Sandbox Code Playgroud)

这样做的问题在于,const int你不能使用STATIC_ASSERT(),你必须采用愚蠢的运行时检查.

有没有办法在当前的C++中正确解决这个问题?
我想我已经读过C++ 0x有一些工具可以做到这一点......


编辑

好的,这个

static const int THIS_LIMIT = 1000;
...
STATIC_ASSERT(THIS_LIMIT > 0);
Run Code Online (Sandbox Code Playgroud)

编译好
但是这个:

static const float THIS_LIMIT = 1000.0f;
...
STATIC_ASSERT(THIS_LIMIT > 0.0f);
Run Code Online (Sandbox Code Playgroud)

才不是.
(在Visual …

c++ static-assert

7
推荐指数
2
解决办法
4536
查看次数

如何做一个静态断言指针转换是微不足道的?

假设我有这些类型:

struct A {
    int a;
};

struct B {
    int b;
};

struct C : public A, public B {
    int c;
};
Run Code Online (Sandbox Code Playgroud)

一个C*指针可以被转换为A*指针,而完全不调整的实际地址.但是当C*被投射时B*,价值必须改变.我想确保我所拥有的两个相关类型可以在不改变地址的情况下相互转换(即没有多重继承,或者基类是派生类的第一个基础).这可以在运行时检查,例如像这样

assert(size_t(static_cast<A*>((C*)0xF000) == 0xF000);
assert(size_t(static_cast<B*>((C*)0xF000) != 0xF000);
Run Code Online (Sandbox Code Playgroud)

这样可行.但是这个信息在编译时是已知的,所以我正在寻找一种方法来对它进行编译时断言.将上面的内容转换为静态断言的明显方法(例如assert,BOOST_STATIC_ASSERT使用g ++ 4.2 将替换为错误的"强制转换为除积分或枚举类型以外的类型"不能出现在常量表达式中).

便携性不是很重要.使用gcc扩展或hacky模板技巧都可以.

更新:发现以前几乎同样的问题:C++,静态检测具有不同地址的基类?.使用offsetof()也是唯一有用的建议.

c++ pointers casting static-assert

7
推荐指数
2
解决办法
1480
查看次数

decltype(constexpr变量)

为什么constexpr变量的decltype失败?

#include <cstdint>
#include <type_traits>

constexpr uint16_t foo(){ return 0;}

constexpr auto cv = foo();
          auto v  = foo();

static_assert( std::is_same< uint16_t, decltype(cv)>::value, "!"); // failed

static_assert( std::is_same< uint16_t, decltype(v) >::value, "!"); // success
Run Code Online (Sandbox Code Playgroud)

c++ static-assert decltype constexpr c++11

7
推荐指数
1
解决办法
1408
查看次数

如何将类型的名称作为字符串嵌入到static_assert()中?

问题

不构建以下内容,因为该消息不是字符串文字.

template<typename T>
struct Foo
{ 
  Foo() 
  {
    static_assert( is_pod<T>::value, typeid(T).name() );
  }
};
Run Code Online (Sandbox Code Playgroud)

最终,如果我尝试编译,我想要一个失败的消息,如"Bar必须是pod-type" Foo<Bar> fb;.

是否可以在编译期间构建此字符串,如static_assert

c++ templates static-assert typeid c++11

7
推荐指数
1
解决办法
577
查看次数

优化,断言和释放模式

考虑一个功能

void f() {
   assert(condition);

   ...
}
Run Code Online (Sandbox Code Playgroud)

在调试模式下,如果启用了断言,则编译器可以自由地假设condition保持,因为如果没有,则不会执行剩余的代码.

但是,在发布模式下,我相信编译器只会看到

void f() {
   ...
}
Run Code Online (Sandbox Code Playgroud)

而且不能再假设了condition.

是否有任何编译器指令或静态断言技巧让编译器了解某些不变量?

c c++ optimization assert static-assert

7
推荐指数
1
解决办法
2090
查看次数

静态在实例化时断言模板类型的大小

我想在实例化时检查以下结构的大小,static_assert以约束未命名struct的紧密包装,因此大小A相当于sizeof(T) * 3.

template <typename T>
struct A
{
   union
   {
      struct { T a, b, c; };
      T arr[3];
   };
};
Run Code Online (Sandbox Code Playgroud)

这可以用

static_assert(sizeof(A<T>) == sizeof(T) * 3, "hey something went wrong");
Run Code Online (Sandbox Code Playgroud)

然而

  • 因为A<T>在其类定义中仍然是一个不完整的类型,所以将上述内容static_assert放入类定义中是不可取的

  • static_assertwith sizeof不评估所有编译器(如Clang)中未实例化的函数内部,因此将其放入虚拟成员函数不是一种选择

  • 放入static_assert构造函数或析构函数将是一个解决方案,但在上面的示例中不存在用户定义的构造函数(考虑聚合),进一步想象多个构造函数的情况,我将避免在所有构造函数中执行断言

  • 继承A自另一个结构,并static_assert在定义中执行A将是一个解决方案,但我想保持结构简单,而不会搞乱辅助结构

我失踪的任何其他解决方案?

我决定取消删除这个问题,并在将来为可能的解决方案保持开放.

c++ templates static-assert

7
推荐指数
1
解决办法
531
查看次数

将CRTP与static_assert一起使用时编译器错误

请考虑以下代码:

template<typename Derived>
struct Base {
    static constexpr int x_base = Derived::x_derived;
    //static_assert(x_base > 1, "Oops");
};

struct Derived : public Base<Derived> {
    static  constexpr int x_derived = 5 ;
};

Base<Derived> obj;
Run Code Online (Sandbox Code Playgroud)

这在gcc上编译很好,但如果我取消注释该static_assert行,它会抱怨

error: incomplete type 'Derived' used in nested name specifier
static constexpr int x_base = Derived::x_derived;
Run Code Online (Sandbox Code Playgroud)

我从4.9到5.3的不同版本的gcc试了一下,我也得到了同样的错误(你可以尝试在godbolt 这里).即使没有static_assert,clang也拒绝编译它,并抱怨

error: no member named 'x_derived' in 'Derived'
static constexpr int x_base = Derived::x_derived;
Run Code Online (Sandbox Code Playgroud)

哪个编译器是正确的(如果有的话)?有没有一种很好的方法来修复代码?

c++ gcc clang static-assert crtp

7
推荐指数
1
解决办法
351
查看次数

c ++:static assert检查使用的const是否在预定义列表中

如何解决这个问题:

我有预定义的整数常量列表:

const auto numbers = {1, 5, 10};
Run Code Online (Sandbox Code Playgroud)

我想使用static_assert(编译时)来检查是否有其他一些const值:

#define SOME_IDENTIFIER 1
Run Code Online (Sandbox Code Playgroud)

在列表中.你会怎么做?可能吗?谢谢!

c++ static-assert

7
推荐指数
1
解决办法
100
查看次数

if constexpr 内部使用 static_assert 格式良好吗?

我昨天读了几个关于在an 子句中使用的答案。我知道根据标准,它被认为是格式错误的(即使某些编译器,包括 MSVC2017,会接受它)。Qt 也会将此标记为错误。static_assert(false, "Some message")elseif constexpr

我的问题是,下面的代码是否符合标准?(我倾向于这么认为,但我想确认一下。)

template <typename TypeOfValue>
static void PushValue(duk_context* ctx, TypeOfValue value) {
    // Push value onto duktape stack
    if constexpr (std::is_same<TypeOfValue, int>::value) {
        // Push int
        duk_push_int(ctx, value);
    } else if constexpr (std::is_same<TypeOfValue, uint32_t>::value) {
        // Push uint
        duk_push_uint(ctx, value);
    } else {
        // Unsupported type
        static_assert(bool_value<false, TypeOfValue>(), "Unsupported type");
    }    
}

template <bool value, typename T>
static constexpr bool bool_value() {return value;}        
Run Code Online (Sandbox Code Playgroud)

编辑: …

c++ static-assert language-lawyer constexpr if-constexpr

7
推荐指数
1
解决办法
1348
查看次数

是否允许比较 static_assert 中静态类字段上的指针?

我试图static_assert通过比较静态字段上的指针来验证程序是否真的有两个从模板生成的不同类。经过一些简化后,程序如下所示:

template<int N> struct C { 
    static int x; 
};

template<int N> int C<N>::x = 0;

int main() { 
    static_assert(&C<0>::x != &C<1>::x); 
}
Run Code Online (Sandbox Code Playgroud)

Clang 没问题,但 GCC 打印错误:

error: non-constant condition for static assertion
Run Code Online (Sandbox Code Playgroud)

演示:https : //gcc.godbolt.org/z/o6dE3GaMK

我想知道在编译时是否真的允许进行这种类型的检查?

c++ static-assert language-lawyer

7
推荐指数
1
解决办法
189
查看次数