标签: 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
查看次数

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检查Q_OBJECT宏

如果给出类型I的声明不包含Q_OBJECT宏,我有一些有趣的需要显示编译错误.我找到了一种不好的方法.实际上它重复了Qt开发人员做同样伎俩的想法:

template<typename T>
void checkForQObjectMacro()
{
    reinterpret_cast<T *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T *>(0));
}
Run Code Online (Sandbox Code Playgroud)

这很好用,但它确实给出了奇怪的错误信息.我想展示一条可读的消息.一种方法是使用static_assert构造.但我不知道如何实现Q_OBJECT宏存在的静态验证条件.也许有人可以提出一个漂亮的黑客?也非常感谢任何想法.

c++ qt static-assert qobject c++11

6
推荐指数
1
解决办法
1065
查看次数

如何使static_assert与SFINAE一起玩得很好

更新

我发布了一份工作草案,rebind作为问题的答案.虽然我没有太多运气找到一种通用的方法来防止static_assert破坏元功能.


基本上我想检查是否T<U, Args...>可以从其他类型构造模板化类型T<V, Args...>.其中TArgs...是在这两种类型相同.问题是,T<>可能有一个static_assert完全打破我的元功能.

以下是我正在尝试做的粗略总结.

template<typename T>
struct fake_alloc {
    using value_type = T;
};

template<typename T, typename Alloc = fake_alloc<T>>
struct fake_cont {
    using value_type = T;
    // comment the line below out, and it compiles, how can I get it to compile without commenting this out???
    static_assert(std::is_same<value_type, typename Alloc::value_type>::value, "must be the same type");
};

template<typename T, typename U, typename = …
Run Code Online (Sandbox Code Playgroud)

c++ static-assert sfinae template-meta-programming c++14

6
推荐指数
1
解决办法
888
查看次数

static_assert具有部分模板特化

template<typename T, typename U = void>
struct S { /* static_assert(0, "type unsupported"); */ };
template<typename T>
struct S<T, typename std::enable_if<std::is_integral<T>::value, void>::type> {
    void foo() {}
};
...
S<int> i;
i.foo();
S<double> d;
// d.foo();
Run Code Online (Sandbox Code Playgroud)

我希望"主模板"永远不会被实例化int,但如果我取消注释static_assert,S<int>实例化将失败.即使是单独的typedef S<int> Si;也无法编译.(GCC 4.9.2 Cygwin)

我想要实现的不是S<double>foo()调用时失败,而是在模板本身的实例化中,以及带有意义的错误消息.我知道我可以typename T::nonexistent_type t;在主模板中执行某些操作,这将阻止模板进行编译,但这不如static_assert消息.(注意:将static_assert函数定义放在主模板中仍然无法编译S<int>)

为什么static_assert即使该模板未实例化也会失败?这个标准是强制性的(或者可能是"未指明的")吗?有没有办法以static_assert我想要的方式失败?

static-assert template-specialization c++11

6
推荐指数
1
解决办法
578
查看次数

仅为特定的模板化类启用模板

这个问题的灵感来自我之前的问题没有模板参数扣除参数包.

请考虑以下代码示例:

#include <memory>
#include <string>

template<typename... FArgs>
class Callback
{
    public:
    class Handle{};
};

class BaseCallbackHandle
{
};

using TypeErasedCallbackHandle = std::unique_ptr<BaseCallbackHandle>;

template<typename H>
TypeErasedCallbackHandle makeTypeErasedCallbackHandle( H handle)
{
   return {};
}

int main()
{
    Callback<int>::Handle h;
    std::string s;
    makeTypeErasedCallbackHandle(h); //should compile fine
    makeTypeErasedCallbackHandle(s); //should raise a compile error
}
Run Code Online (Sandbox Code Playgroud)

另见http://coliru.stacked-crooked.com/a/5f2a2e816eef6afd

函数模板makeTypeErasedCallbackHandle现在将任何类作为输入参数.有没有办法确保(例如使用static-assert或enable_if),只允许Callback<FArgs...>::Handle(有任何FArgs)HCallback<int>::Handle应该编译的例子,但是std::string会失败.

c++ static-assert enable-if variadic-templates c++11

6
推荐指数
1
解决办法
195
查看次数

解决静态断言中的不完整类型

当表达式取决于类类型本身时,有没有办法在类内进行 static_assert ?也许延迟评估直到类型完成或模板实例化之后?

示例代码:

#include <type_traits>

template<typename T>
struct Test {
   T x = 0; // make non-trivial
   static_assert(std::is_trivial<Test<T>>::value, "");
};

int main() {
    // would like static assert failure, instead get 'incomplete type' error
    Test<int> test1;
    Test<float> test2;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ templates static-assert type-traits

6
推荐指数
1
解决办法
977
查看次数

在C++模板实例化期间获取原始结构/类名

template<typename T> struct S {};
template<typename T> struct R {};

int main() {
  typedef S<double> s1;
  typedef S<int> s2;
  typedef R<int> s3;
  static_assert(xxx<s1, s2>::value,
                "No, assertion must not be raised");
  static_assert(xxx<s2, s3>::value,
                "Yes, assertion must be raised");
}
Run Code Online (Sandbox Code Playgroud)

所以,我希望在编译时返回false xxx<s1, s2>::valuexxx<s2, s3>::value返回true.

在C++中是不是存在xxx?或者,在C++中理论上是否存在xxx,但可能还没有人做过呢?

c++ static-assert template-meta-programming

6
推荐指数
1
解决办法
175
查看次数

检测功能失败static_assert的习惯用法

有没有办法使用检测习惯用法(或另一种方法)来测试一个函数是否对给定的模板参数有效,如果它由于static_assert?而失败?

下面的例子说明了foo(失败的返回类型计算)的有效性是按预期检测到的,但是bar(失败的static_assert)的有效性则没有.

#include <iostream>
#include <type_traits>

template <typename... T> using void_t = void;

template <class AlwaysVoid, template<class...> class Op, class... Args>
struct detector: std::false_type { };

template <template<class...> class Op, class... Args>
struct detector<void_t<Op<Args...>>, Op, Args...>: std::true_type { };

template <template<class...> class Op, class... Args>
constexpr bool is_detected = detector<void, Op, Args...>::value;

template <typename T>
std::enable_if_t<!std::is_void<T>::value> foo() {
  std::cout << "foo" << std::endl;
}

template <typename T>
void bar() { …
Run Code Online (Sandbox Code Playgroud)

c++ static-assert sfinae c++14

6
推荐指数
1
解决办法
217
查看次数

如果函数被称为constexpr,则有条件static_assert

我知道有一个针对constexpr()运算符的提议,但这尚未在gcc / clang中实现。我也知道使用一些技巧来实现,例如机器代码编辑:

http://saadahmad.ca/detecting-evaluation-context-inside-constexpr-functions/

我想知道是否有某种受限的解决方案:

struct F {
    constexpr F(int v) {
         if constexpr(constexpr()) {
             static_assert(v > 0);
         }
         else {
             assert(v > 0);
         }
    }
};

// ...

constexpr F f{0}; // should trigger a compile-time error
Run Code Online (Sandbox Code Playgroud)

我知道无法以这种方式使用static_assert,但这只是为了澄清问题。

c++ static-assert constexpr

6
推荐指数
1
解决办法
167
查看次数