#include <iostream>
#include <array>
int main(int argc, char **argv) {
constexpr const std::array<int, 2> arr {{ 0, 1 }};
constexpr const int arr2[] = { 0, 1};
static_assert(arr[0] == arr2[0], "asdf");
static_assert(arr[1] == arr2[1], "asdfasdf");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当编译gcc 4.8.2和4.9.1使用g++ test.cpp --std=c++11,编译成功.当编译clang 3.4和3.5利用clang++ test.cpp --std=c++11然而,编译失败:
test.cpp:8:16: error: static_assert expression is not an integral constant expression
static_assert(arr[0] == arr2[0], "asdf");
^~~~~~~~~~~~~~~~~
test.cpp:8:16: note: non-constexpr function 'operator[]' cannot be used …Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
SomeType x=getX();
for(auto mask = 1u<<(CHAR_BIT*sizeof x - 1);/*...*/;/*...*/)
{
static_assert(sizeof mask>=sizeof x, "Type of numeric parameter is too long");
/*...*/
}
Run Code Online (Sandbox Code Playgroud)
在这里,mask将具有type unsigned。假设SomeType是long long。然后,mask由于移动过多,初始化会具有不确定的行为。但是OTOH中有一个static_assert,用于检查在运行时不会发生未定义的行为(因为代码将无法编译)。
但是,由于UB可能导致时间悖论和其他意外事件,因此我不确定static_assert在这种情况下是否可以保证它确实有效。有什么理由可以确定吗?还是应该static_assert在初始化之前重做此代码mask?
在模板化函数中,其中一个参数是类型的标准库容器T,我可以轻松地静态断言这T是一个有序容器吗?
有没有更优雅的方式来做这个比做类型特定的事情,比如测试一个hash_function()功能的存在来区分std::map和std::unordered_map?
是否可以像在C++中的static_assert一样在Swift中编译一个编译时断言?也许某种方式利用泛型的类型约束来强制编译器中断?
有没有办法在标题中的那个点上使用static_assert类型T 不完整?如果有人在他们不应该的地方添加#includes,那么这个想法就会产生编译错误.
使用该链接的答案,
namespace
{
template<class T, int discriminator>
struct is_complete {
static T & getT();
static char (& pass(T))[2];
static char pass(...);
static const bool value = sizeof(pass(getT()))==2;
};
}
#define IS_COMPLETE(X) is_complete<X,__COUNTER__>::value
class GType;
static_assert(!IS_COMPLETE(GType),"no cheating!");
Run Code Online (Sandbox Code Playgroud)
不幸的是,这给出了"无效使用incomlete类型"错误,哦.有没有办法断言否定?
我写了几个constexpr函数,并在static_asserts中使用它们来控制一些资源限制.但是我不仅要强制执行编译时谓词,还要查看在正常编译过程中计算的实际值,或者至少在断言失败时.
有很多方法可以在编译期间打印字符串消息,但是打印constexpr计算的结果是什么?
我希望以下代码失败并static_assert检查最后一行.但是在MSVC2015和gcc 6.2中,它成功编译.它确实无法在clang 3.9中按预期编译.这是编译器错误还是static_assert内部不起作用decltype()?
#include <tuple>
#include <type_traits>
template<typename T>
struct Wrapper {};
template<typename T, typename U>
constexpr std::tuple<T, U> operator|(Wrapper<T>, Wrapper<U>)
{
static_assert(std::is_same<T,U>::value == false, "can't combine two of the same type");
return std::tuple<T, U> {};
}
struct A {};
struct B {};
constexpr Wrapper<A> aaa = {};
constexpr Wrapper<B> bbb = {};
constexpr auto shouldPass1 = aaa | bbb;
//constexpr auto shouldFail1 = aaa | aaa; // fails static assert as expected
using …Run Code Online (Sandbox Code Playgroud) 提供static_assert模板通常很有帮助.在模板不应该以某种方式实例化的情况下,我经常这样做
template<typename T, typename = void>
struct S
{
static_assert(false, "Unconditional error");
static_assert(sizeof(T) != sizeof(T), "Error on instantiation");
};
template<typename T>
struct S<T, std::enable_if_t<std::is_integral_v<T>>>
{
// ...
};
Run Code Online (Sandbox Code Playgroud)
static_assert即使没有实例化,第一个将立即失败S,而如果没有实例化将导致主模板,第二个将成功.
第二个static_assert显然是一个重言式,但它"取决于" T,以达到预期的效果.但这有保证吗?是否允许编译器评估这些重言式?
当前,即使对它的所有调用确实为,也无法用于static_assert验证constexpr函数的参数constexpr。这是有道理的,因为在某些其他模块尝试调用该函数的情况下,编译器仍必须为此函数创建一个非constexpr实例。可悲的是,即使函数是static或位于匿名名称空间中,也是如此。
然而,C ++ 20将引入一个新的关键字consteval,类似于constexpr但不允许以非constexpr的方式调用函数。在这种情况下,编译器可以确定在编译时始终知道函数参数。因此,从理论上讲,应该有可能使用进行验证static_assert。
问题是:标准允许吗?
例:
#include <iostream>
consteval char operator""_bchar(const char text[], const size_t length)
{
static_assert(length == 8, "Binary char has to have 8 digits!"); // <-- This is currently not possible.
uint8_t byte = 0;
for (size_t i = 0; i != length; ++i)
{
byte <<= 1;
byte |= text[i] == '1' ? 0b00000001 : 0b00000000;
}
return byte;
}
int main() …Run Code Online (Sandbox Code Playgroud) 在 C++11 constexpr 函数中,assert()不可能使用第二个语句,例如 an 。Astatic_assert()很好,但如果该函数被称为“正常”函数,则它不起作用。逗号运算符可以来帮助wrto。的assert(),而是丑陋和一些工具吐出它的警告。
考虑这样的“getter”,它在断言旁边是完全可构造的。但是我想为运行时和编译时保留某种断言,但不能仅根据“constexpr”上下文进行重载。
template<int Size>
struct Array {
int m_vals[Size];
constexpr const int& getElement( int idx ) const
{
ASSERT( idx < Size ); // a no-go for constexpr funcs in c++11
// not possible, even in constexpr calls as being pointed out, but what I would like:
static_assert( idx < Size, "out-of-bounds" );
return m_vals[idx];
}
};
Run Code Online (Sandbox Code Playgroud)
附带条件:C++11,无堆,无异常,无编译器细节。
注意正如评论者指出的那样(谢谢!),static_assert论点是不可能的(但会很好)。在这种情况下,编译器在越界访问时给了我一个不同的错误。