static_assert可以检查类型是否为向量?IE,一个int会提出断言,而一个vector<int>不会.
我正在考虑以下方面的事情:
static_assert(decltype(T) == std::vector, "Some error")
Run Code Online (Sandbox Code Playgroud) 有没有办法在编译时打印a constexpr或#defined值的值?我想要相当于std::cout <<或某种方式来做类似的事情
constexpr int PI_INT = 4;
static_assert(PI_INT == 3,
const_str_join("PI_INT must be 3, not ", const_int_to_str(PI_INT)));
Run Code Online (Sandbox Code Playgroud)
编辑:我可以用constexprs 做一些基本的编译时打印,至少在gcc上做类似的事情
template <int v>
struct display_non_zero_int_value;
template <>
struct display_non_zero_int_value<0> { static constexpr bool foo = true; };
static constexpr int v = 1;
static_assert(v == 0 && display_non_zero_int_value<v>::foo, "v == 0");
Run Code Online (Sandbox Code Playgroud)
这给了我error: incomplete type ‘display_non_zero_int_value<1>’ used in nested name specifier static_assert(v == 0 && display_non_zero_int_value<v>::foo, "v == 0");.(另一方面,icpc不太有帮助,只是说error: incomplete …
我正在为包含static_asserts 的源代码库编写单元测试套件.static_assert在设计方面,我希望保证这些不会超出他们的期望.所以我希望能够测试它们.
我当然可以添加无法编译的接口单元测试,这些测试会导致static asserts被各种各样的手段侵犯,并评论或#if 0全部出来,我个人向用户保证,如果其中任何一个未被注释,那么他们会发现库没有编译.
但这太荒谬了.相反,我想有一些装置,在单元测试套件的上下文中,static_assert用一个等效激发的运行时异常替换,测试框架可以捕获并报告生效:这段代码将static_assert在真实中编辑建立.
我是否忽略了一些明显的原因,为什么这会是一个愚蠢的想法?
如果没有,怎么办呢?宏观设备是一种显而易见的方法,我不排除它.但也许,最好是模板专业化或SFINAE方法?
我正在努力了解它的用处static_assert,我想知道它是否可以帮助我执行设计,如果是,那么如何.
我有一个通用的模板类,它在另一个模板类中隐藏它自己的实现,这个类是基于模板类型的大小而部分专用的.以下是此设计的简要概述:
template <class T, size_t S = sizeof(T)>
struct Helper;
template <class T>
struct Helper<T, sizeof(long)>
{
static T bar();
};
// ... other specializations ...
template <class T>
class Foo
{
public:
T bar()
{
return Helper<T>::bar();
}
};
Run Code Online (Sandbox Code Playgroud)
美孚如果尺寸仅支持T由一个专业化的支持助手.例如,Foo<long>并且Foo<unsigned long>都受支持.但是,假设用户尝试构造一个Foo<bool>.通常,这会产生错误,因为没有定义Helper for的特化bool,这是预期的行为.
static_assert在此设计中是否有任何方法可以为此界面的用户提供更多有用的错误?
此外,我还想限制用户使用特定类型,即使大小可能是正确的.例如,Foo<float>不应该被允许.现在,我知道强制执行此操作的唯一方法是通过文档中的大胆注释.:)
我需要确保模板结构与其成员的大小完全相同.static_assert似乎是这里的首选工具.但是,我不能static_assert在结构本身内部使用,因为那里的大小还不知道.这是我想要的:
template<typename T1,typename T2>
struct foo {
T1 v1;
T2 v2;
// Doesn't compile, invalid application of sizeof to incomplete type
static_assert(sizeof(foo<T1,T2>)==sizeof(T1)+sizeof(T2),"Struct size invalid");
};
Run Code Online (Sandbox Code Playgroud)
这不起作用.那怎么办呢?我不想让实例化模板的人在每个实例化中检查自己.只要实例化结构,检查应该是完全自动的.
我们现有的编译时断言实现基于负数组索引,并且它在GCC上提供差的诊断输出.C++ 0x static_assert是一个非常好的功能,它提供的诊断输出要好得多.我知道GCC已经实现了一些C++ 0x功能.有谁知道是否static_assert是其中之一,如果它是那么GCC版本?
内存使用在我的应用程序中非常重要.因此,我有特定的断言,在编译时检查内存大小,如果大小与我们之前认为正确的大小不同,则给出static_assert.
我已经定义了一个像这样的宏:
#define CHECKMEM(mytype, size) static_assert((sizeof(objectType) == size)), "Size incorrect for " #mytype "!");
Run Code Online (Sandbox Code Playgroud)
这个宏使得编写它非常容易:
CHECKMEM(Book,144);
CHECKMEM(Library,80);
Run Code Online (Sandbox Code Playgroud)
问题是当这个static_assert出现时,可能很难找出新的大小应该是什么(例如通过使用隐藏的编译器选项"/ d1 reportAllClassLayout").如果我可以包含实际大小会更方便,所以代替:
Book的大小不正确!
它会显示出来
Book的大小不正确!(预计144,大小为152)
我试着写这样的东西:
#define CHECKMEM(mytype, size) static_assert((sizeof(objectType) == size)), "Size incorrect for " #mytype "! (expected" #size ", size is " #sizeof(mytype) ")");
Run Code Online (Sandbox Code Playgroud)
但是你不能在函数调用中使用stringize(#)运算符.
我也尝试添加双串联技巧,如下所示:
#define STR1(x) #x
#define STR2(x) STR1(x)
#define CHECKMEM(mytype, size) static_assert((sizeof(objectType) == size)), "Size incorrect for " #mytype "! (expected" #size ", size is " STR2(sizeof(mytype)) ")");
Run Code Online (Sandbox Code Playgroud)
但不是打印size is 152它打印size is sizeof(Book) …
我想创建一个静态分配2 ^ N字节数组的结构,但我不希望此结构的用户将此大小指定为指数.例:
my_stupid_array<char, 32> a1; // I want this!
my_stupid_array<char, 5> a2; // And not this...
Run Code Online (Sandbox Code Playgroud)
如何检查此模板参数是否为2的幂并警告用户有关于此的好消息?
我已经能够通过一个简单的模板检查这个:
template<int N>
struct is_power_of_two {
enum {val = (N >= 1) & !(N & (N - 1))};
};
Run Code Online (Sandbox Code Playgroud)
但是,我无法通过合理的消息警告用户.有任何想法吗?
编辑
修复了模棱两可的例子.
编辑
1确实是2的幂.修好了!:)
编辑
使用BOOST_STATIC_ASSERT,我收到此代码与GCC的编译错误:
template<int N>
struct is_power_of_two {
enum {val = (N >= 1) & !(N & (N - 1))};
BOOST_STATIC_ASSERT(val);
};
Run Code Online (Sandbox Code Playgroud)
错误
..\main.cpp:29:1: error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>'
Run Code Online (Sandbox Code Playgroud)
编辑 …
假设我有以下简化程序:
#include <cassert>
struct Dimensions {
Dimensions& operator=(int i) {
assert(i != 0);
return *this;
}
};
int getDim();
int main() {
Dimensions dims;
dims = getDim();//ok, just use runtime assert
dims = 0;//compile error wanted here
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在第一种情况(getDim)中,无法检查编译时,因此我们很高兴在运行时检查它。
但是在理论上看起来可行dims = 0;时,是否也可以通过某种方式检测到编译(对于第二种情况)?(甚至可能带有某种类型的重载或包装?)
我在看这个源代码
template<char... digits>
struct conv2bin;
template<char high, char... digits>
struct conv2bin<high, digits...> {
static_assert(high == '0' || high == '1', "no bin num!");
static int const value = (high - '0') * (1 << sizeof...(digits)) +
conv2bin<digits...>::value;
};
template<char high>
struct conv2bin<high> {
static_assert(high == '0' || high == '1', "no bin num!");
static int const value = (high - '0');
};
template<char... digits>
constexpr int operator "" _b() {
return conv2bin<digits...>::value;
}
int array[1010_b];
Run Code Online (Sandbox Code Playgroud)
我想知道这是否是有效的C++.
template<char high, char... digits> …Run Code Online (Sandbox Code Playgroud) c++ static-assert user-defined-literals variadic-templates c++11
static-assert ×10
c++ ×9
c++11 ×6
templates ×3
constexpr ×2
c++17 ×1
compile-time ×1
cout ×1
gcc ×1
sizeof ×1
stringify ×1
unit-testing ×1