标签: static-assert

何时使用`static_assert`而不是SFINAE?

我一直在使用(并且看到用过)static_assert来标记模板参数值的不需要的值.然而,对于我遇到的所有情况,通过SFINAE禁用那些不需要的值似乎更好,更优雅.例如

template<typename T,
         class = std::enable_if<std::is_floating_point<T>::value>::type>
struct Foo { ... };
Run Code Online (Sandbox Code Playgroud)

代替

template<typename T>
struct Foo {
  static_assert(std::is_floating_point<T>::value,
                "Foo<T>: T must be floating point :-(");
  ...
};
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:何时使用static_assert而不是SFINAE?为什么?

编辑

我认为到目前为止我所学到的是以下内容

1 SFINAE是一个多功能且功能强大但可能非常复杂的工具,可用于许多任务,包括功能过载解决(有些人认为这是其唯一目的).

2 SFINAE可以以一种相对简单的方式使用static_assert,除非它出现在(类或函数的)声明中而不是它的定义(或者是否可以插入static_assert一个类,例如,类前向声明​​?) .这使得更加逐字,更清晰的代码.然而,因为SFINAE很复杂,所以它往往比简单的更难static_assert.

3另一方面,static_assert有一个更清晰的编译器错误消息的好处,有些人似乎认为这两者的主要目的.

c++ templates static-assert sfinae c++11

24
推荐指数
4
解决办法
3761
查看次数

如何在编译时检查两种类型是否相同(如果它与Boost强类型定义一起使用,则为奖励积分)

我想知道是否有可能在编译时检查两种类型是否相同.我想出的是(idk如果它有效,因为它感觉hackish和IDK标准好,所以IDK在测试时要寻找什么).

#include <boost/strong_typedef.hpp>
BOOST_STRONG_TYPEDEF(double, cm);
BOOST_STRONG_TYPEDEF(double, inch);
template<typename T, typename U>
static constexpr void __help() 
{
}
template<typename T, typename U>
class AreSameType
{
    public:
    constexpr operator bool()
    {
     return &__help<T,U> == &__help<U,T>;
    };
};
Run Code Online (Sandbox Code Playgroud)

用法:

int main()
{
        static_assert(AreSameType<double,float>()== false, "oh noes1");
        static_assert(AreSameType<double,double>()== true, "oh noes2");
        static_assert(AreSameType<int*,double*>()== false, "oh noes3");
        static_assert(AreSameType<double*,double>()== false, "oh noes4");
        static_assert(AreSameType<const double,double>()== false, "oh noes5");
        static_assert(AreSameType<inch,cm>()== true, "oh expected"); //fires
}
Run Code Online (Sandbox Code Playgroud)

所以

1)有更好的方法吗?
2)这个功能黑客的地址保证按标准工作(我打赌不会:))?

c++ static-assert template-meta-programming constexpr c++11

24
推荐指数
1
解决办法
1万
查看次数

如何将模板类限制为某些内置类型?

这个问题已经讨论了几次,但我发现的所有解决方案要么不起作用,要么基于boost的静态断言.我的问题很简单.我有一个类,我只想允许真正的类型(double和float).如果我尝试使用float或double以外的类型实例化类,我想要一个编译时错误.我正在使用Visual C++ 11.这是我尝试过的:

template <typename RealType>
class A
{
  // Warning C4346
  static_assert(std::is_same<RealType, double>::value || std::is_same<RealType, float>::value);
}


template <typename RealType>
class A
{
  // Error C2062: type 'unknown' unexpected
  static_assert(decltype(RealType) == double || decltype(RealType) == float);
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?提前致谢!

c++ templates static-assert c++11 visual-studio-2012

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

Clang和GCC vs MSVC和ICC:复制/移动构造函数中的static_assert是否需要工作,如果复制/移动省略也适用?

我有一个我static_assert的模板结构的移动构造函数.这是否static_assert需要编译器考虑,即使可以复制省略?

这是精简的场景:

#include <type_traits>

template<typename T>
struct X
{
  X(X&&) { static_assert(std::is_same<void, T>::value, "Intentional Failure"); }
};

auto impl() -> X<int>;    
auto test() -> decltype(impl())
{
  return impl();
}

int main()
{
  test();
}
Run Code Online (Sandbox Code Playgroud)

GCC和Clang同意评估static_assert并且无法编译.
另一方面,MSCV和ICC编译代码就好了.

有趣的是,当我删除move构造函数的定义时,只需将其声明为:

template<typename T>
struct X
{
  X(X&&);
};
Run Code Online (Sandbox Code Playgroud)

GCC和Clang现在也编译代码.因此,所有编译器似乎都同意移动构造函数的定义与复制省略无关.

问题:
如果static_assert复制/移动构造函数中有a ,即使可以复制/移动省略,标准是否要求对其进行评估?

c++ static-assert language-lawyer copy-elision c++11

24
推荐指数
1
解决办法
785
查看次数

如果表达式是constexpr,则为static_assert

我想创建一个类模板

template <class T>
class X {
  // here I'll use T::value (among other things)
};
Run Code Online (Sandbox Code Playgroud)

T::value通常是constexpr静态变量,但并非总是如此.T::value必须是正值,所以我想在编译期间让人们知道它,如果可能的话.

如果T::value总是constexpr,我会添加static_assert喜欢

static_assert(T::value > 0, "need positive number");
Run Code Online (Sandbox Code Playgroud)

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

c++ static-assert sfinae type-traits

24
推荐指数
1
解决办法
1565
查看次数

没有提升的BOOST_STATIC_ASSERT

由于在我工作的公司中禁止使用boost,我需要在纯C++中实现其功能.我已经研究了增强源,但它们似乎太复杂了,至少对我而言.我知道static_assert()在C++ 0x标准中有一些东西,但我不想使用任何C++ 0x功能.

c++ boost replace static-assert

23
推荐指数
3
解决办法
8901
查看次数

有没有办法将static_assert转换为ISO C++ 11中的表达式?

在C++ 11中,编写是合法的,例如:

int b = (some_function_returning_void(), 1020);
Run Code Online (Sandbox Code Playgroud)

你会回来1020.但它不会让你写:

int b = (static_assert(2 > 1, "all is lost"), 304);
Run Code Online (Sandbox Code Playgroud)

文档解释了static_assert(显然是一个关键字)可能出现的合法位置:

静态断言声明可能出现在块作用域(作为块声明)和类体内(作为成员声明)

只是为了它,我尝试了几件事,直到这个工作:

int b = ({static_assert(2 > 1, "all is lost"); 304;});
Run Code Online (Sandbox Code Playgroud)

但随着-Wpedantic我的到来"warning: ISO C++ forbids braced-groups within expressions".有趣的是,这些被称为"语句表达式"并在Linux内核中使用.

但我们想象一下,我想留下来-Wpedantic.有没有干净的解决方法?

c++ static-assert c++11

23
推荐指数
2
解决办法
1465
查看次数

是否有编译时func /宏来确定C++ 0x结构是否为POD?

我想要一个C++ 0x static_assert来测试给定的结构类型是否是POD(以防止其他程序员无意中用新成员破坏它).即

struct A // is a POD type
{
   int x,y,z;
}

struct B // is not a POD type (has a nondefault ctor)
{
   int x,y,z; 
   B( int _x, int _y, int _z ) : x(_x), y(_y), z(_z) {}
}

void CompileTimeAsserts()
{
  static_assert( is_pod_type( A ) , "This assert should not fire." );
  static_assert( is_pod_type( B ) , "This assert will fire and scold whoever added a ctor to the POD type." ); …
Run Code Online (Sandbox Code Playgroud)

c++ static-assert type-traits c++11

22
推荐指数
1
解决办法
3265
查看次数

为什么std :: make_pair不返回一对?或者是吗?

我的内部健全性检查失败,所以我在Stackoverflow上重新运行它.

以下代码:

#include <iostream>
#include <typeinfo>
#include <utility>

int main()
{
    constexpr auto pair_of_ints = std::make_pair(1, 2);
    std::cerr << typeid(pair_of_ints).name();
    //static_assert(std::is_same<decltype(pair_of_ints), std::pair<int, int>>::value, "WTF");
}
Run Code Online (Sandbox Code Playgroud)

std::__1::pair<int, int>在我的系统上生成受损的符号名称(XCode Clang 8.x).

如果我然后启用它static_assert,则失败.我不知道为什么.我怎样才能做到这一点?我有一个函数,它返回一个对或元组,具体取决于传递给它的参数,并希望验证它在正确的情况下实际返回一对或元组.

c++ static-assert c++11 std-pair

20
推荐指数
1
解决办法
2554
查看次数

如何使用std :: is_volatile?

我试图禁止对volatile类型进行特定操作.为了实现这一点,我试图使用std::is_volatile,但下面的代码编译没有错误,这不是我想要的.

为什么在下面的情况下是is_volatile::value 的?

#include <type_traits>

template<typename T>
inline void DoStuff(T val) {
    static_assert(!std::is_volatile<T>::value, "No volatile types plz");
    //...
}

int main() {
    volatile char sometext[261];
    DoStuff(sometext);
}
Run Code Online (Sandbox Code Playgroud)

c++ templates static-assert c++11

19
推荐指数
2
解决办法
1511
查看次数