标签: static-assert

如何添加静态断言来检查变量是否是静态的?

我有一个仅适用于静态局部变量的宏(因为它使用内联汇编表示法来提取有关变量的数据)。我需要一种方法来强制宏的输入确实是静态局部变量:

正确的:

func f()
{
    static int x;
    my_macro(x);
}
Run Code Online (Sandbox Code Playgroud)

不正确:

func f()
{
    int x;
    my_macro(x);
}
Run Code Online (Sandbox Code Playgroud)

我使用 GCC 来处理 C(没有 C++)。

c static static-assert

4
推荐指数
1
解决办法
1107
查看次数

/boost/lockfree/queue.hpp:错误:静态断言失败:(boost :: has_trivial_destructor <T> :: value)

我试图取代boost::lockfree::queuestd::queue在这个文件https://github.com/zaphoyd/websocketpp/blob/experimental/examples/broadcast_server/broadcast_server.cpp

我补充说#include <boost/lockfree/queue.hpp>; 更改后的行130,std::queue<action> m_actions;boost::lockfree::queue<action> m_actions;; 删除所有与锁定有关的行; 而改变的线103,m_actions.pop();m_actions.pop(a);.

当我scons broadcast_server_lockfree在项目根目录中添加broadcast_server_lockfree = SConscript('#/broadcast_server_lockfree/SConscript',variant_dir = builddir + 'broadcast_server_lockfree',duplicate = 0)项目根目录SConstruct并在目录中使用broadcast_server's 后,我得到这些错误:SConstructbroadcast_server_lockfree

root@server:~/websocketpp-experimental# scons broadcast_server_lockfree
scons: Reading SConscript files ...
C++11 build environment partially enabled
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: build/release/broadcast_server_lockfree
g++ -o build/release/broadcast_server_lockfree/broadcast_server_lockfree.o -c …
Run Code Online (Sandbox Code Playgroud)

c++ queue boost static-assert lock-free

4
推荐指数
1
解决办法
5796
查看次数

std :: disjunction中的短路模板专业化

一些背景:

我正在努力整理一个模板化的类,作为模板特化的一部分,它推导出一个类型用于其中一个成员.这个数据成员需要支持通过线路流式传输,并且我试图保持系统尽可能灵活和可扩展(目标是可以通过修改专业化的一些高级元素来创建该类型的新变体逻辑没有进入实现代码的内容).一些现有的用法将此数据成员专门化为枚举,并且流代码支持将此值来回转换为32位整数以通过线路传输.

因为可以定义(隐式或显式)枚举以由不同类型支持 - 在这种情况下最危险的是64位值 - 我希望能够强制执行,如果解析的类型是枚举,它的底层类型必须是一个32位整数(更一般地说,我只需要强制它最多 32位,但是一旦更简单的情况工作,我会担心这种复杂性).

我尝试的解决方案:

type_traits提供的一些工具拼接在一起,我想出了以下内容:

#include <cstdint>
#include <type_traits>

using TestedType = /* Logic for deducing a type */;
constexpr bool nonEnumOrIntBacked =
    !std::is_enum_v<TestedType>
    || std::is_same_v<std::underlying_type_t<TestedType>, std::int32_t>;
static_assert(nonEnumOrIntBacked,
    "TestedType is an enum backed by something other than a 32-bit integer");
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试编译它时(在最新更新时使用Visual Studio 2017),我遇到了错误文本 'TestedType': only enumeration type is allowed as an argument to compiler intrinsic type trait '__underlying_type'.看到这个,我尝试了使用std :: disjunction的替代公式,我认为如果早期条件的计算结果为true,我应该对模板进行短路评估(我已经省略了std限定符以使其更具可读性):

disjunction_v<
    negation<is_enum<TestedType>>,
    is_same<underlying_type_t<TestedType>, int32_t>
>;
Run Code Online (Sandbox Code Playgroud)

我还试图捆绑的违规使用underlying_type_t …

c++ templates static-assert visual-c++ c++17

4
推荐指数
1
解决办法
178
查看次数

如果没有 if-constexpr 成功,触发编译时错误的最佳方法是什么?

我有一系列很长的if constexpr语句,如果没有一个成功,我想触发编译时错误。

具体来说,我有一个抽象语法树,我想将其结果转换为我可能需要的一组特定类型。我有 AsInt()、AsDouble() 等正在工作,但我需要能够根据提供的类型更动态地执行此操作。

就目前情况而言,我已经编写了一个模板化的 As() 成员函数,但它的错误检查很笨拙。具体来说,使用静态断言需要一个笨拙的测试条件。这是一个简化版本:

template <typename T>
T As() {
  if constexpr (std::is_same_v<T,int>) return AsInt();
  if constexpr (std::is_same_v<T,double>) return AsDouble();
  ...
  if constexpr (std::is_same_v<T,std::string>) return AsString();

  static_assert( std::is_same_v<T,int>
                 || std::is_same_v<T,double>
                 || ...
                 || std::is_same_v<T,std::string>,
                 "Invalid template type for As()" );
}
Run Code Online (Sandbox Code Playgroud)

如果所有条件都失败,是否有更简单的方法来触发静态断言(或等效方法)?

c++ static-assert type-traits if-constexpr

4
推荐指数
1
解决办法
884
查看次数

C:断言表达式是字符串文字

我想要一个静态断言来确保给定的表达式是字符串文字。我试过这个:

#define SAME_TYPES(x, y)                    __builtin_types_compatible_p(typeof(x), typeof(y))
#define IS_ARRAY(x)                         !SAME_TYPES((x), &(x)[0])
#define IS_COMPILE_TIME_STR(x)              IS_ARRAY(x) && #x[0] == '"'
#define ASSERT_COMPILE_TIME_STR(x)          static_assert(IS_COMPILE_TIME_STR(x), "Only static allocated compile time strings are allowed, but got this: " #x)

/*
 * ASSERT_COMPILE_TIME_STR("hey"); <-- this is fine
 * ASSERT_COMPILE_TIME_STR(1234);  <-- this should fail
 */
Run Code Online (Sandbox Code Playgroud)

不幸的是,ASSERT_COMPILE_TIME_STR不起作用,因为#x[0] == '"'似乎不是编译时常量。

还有其他方法可以实现这一目标吗?它只需要使用 gcc 进行编译,所以任何类型的扩展都可以:)

多谢

c gcc static-assert string-literals

4
推荐指数
1
解决办法
184
查看次数

如何使用静态断言和类型特征阻止嵌套模板类型中的菱形图案?

可能重复:
有没有办法阻止使用静态断言和类型特征从两次派生类?

我想要防止的是不止一个基于C的模板来自D(即应该只有一个C派生的实例).希望C或B中的静态断言可以解决这个问题.

// My Classes
template <class T>
class A {};

class B {};

template <class T, class S>
class C : public B, public virtual A<T> {};

// Someone elses code using my classes
class D : public C<Type1, Type2>, public C<Type3, Type4>
{
};
Run Code Online (Sandbox Code Playgroud)

c++ templates static-assert type-traits

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

为什么这个静态断言不起作用?

我试图使用pre-C++ 11静态断言.我找到了这个这个问题,但不知怎的,我不能让它运行:

#define STATIC_ASSERT(x) \
    do { \
        const static char dummy[(x)?1:-1] = {0};\
    } while(0)

struct bar {
    int value;
    template<typename T> void setValue(T x);
};
template<typename T> void bar::setValue(T x) { STATIC_ASSERT(1==0); }
template<> void bar::setValue(int x) { value = x;}

int main(){
    bar b;
    int c = 1;
    b.setValue(c);    
}
Run Code Online (Sandbox Code Playgroud)

编译此(gcc)会导致

错误:数组'dummy'的大小为负数

我希望只有当我setValue用除了以外的任何东西打电话时才会出现这个错误int.我也尝试了其他提出的解决方案,但结果大致相同:即使我没有用除了以外的任何东西实例化模板,也会出现错误int.我究竟做错了什么?

c++ templates static-assert c++03

3
推荐指数
1
解决办法
149
查看次数

static_assert和类模板

我的static_assert功能有问题.当我直接实例化一个类模板时,一切都按预期工作.但是当我将它作为不同类模板的参数传递时,static_assert不起作用.

template <int X>
class A{
    static_assert(X == 0, "X != 0");
};

template <class T>
class B{

};

B<A<1>> b;           // Static assert does not work
A<1>    a;           // error: static assertion failed: X != 0
Run Code Online (Sandbox Code Playgroud)

编辑

谢谢大家的答案.有没有办法显式实例化A而不创建A实例/从A继承?我在尝试这个:

template <int X>
class A{
    static_assert(X == 0, "X != 0");
};

template <class T>
class B;

template <template <int X> class T, int X>
class B<T<X>>{
    template class T<X>;
};
Run Code Online (Sandbox Code Playgroud)

但这是不正确的.

c++ templates static-assert c++11

3
推荐指数
1
解决办法
1035
查看次数

模板特化中的静态断言即使未实例化也会失败

以下代码编译正常:

#include <type_traits>

template <typename T> struct dependent_true : std::true_type { };
template <typename T> struct dependent_false : std::false_type { };

template <bool B = false>
class X { static_assert(dependent_false<X>::value); };

template <>
class X<true> { static_assert(dependent_true<X>::value); };

int main() {
   X<true> x;
}
Run Code Online (Sandbox Code Playgroud)

也就是说,static_assert不评估主模板中的内容.相反,如果我切换到:

template <bool B = false>
class X { static_assert(dependent_true<X>::value); };

template <>
class X<true> { static_assert(dependent_false<X>::value); };

int main() {
    X<false> x;
}
Run Code Online (Sandbox Code Playgroud)

然后,模板特化中的静态断言失败,即使它没有实例化.我只是想知道为什么.我在GCC 8和Clang 6(-std=c++17)中观察到了这种行为.

现场演示:https: …

c++ static-assert template-specialization language-lawyer

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

编译时检查以确保结构中的任何地方都没有填充

有没有一种方法可以编写一个编译时断言来检查某种类型是否有填充?

例如:

struct This_Should_Succeed
{
    int a;
    int b;
    int c;
};

struct This_Should_Fail
{
    int a;
    char b;
    // because there are 3 bytes of padding here
    int c;
};
Run Code Online (Sandbox Code Playgroud)

c++ struct padding static-assert

3
推荐指数
2
解决办法
130
查看次数