你能举个例子static_assert(...)来优雅地解决问题吗?
我熟悉运行时assert(...).我什么时候应该static_assert(...)比常规更喜欢assert(...)?
此外,boost有一个叫做的东西BOOST_STATIC_ASSERT,它是一样的static_assert(...)吗?
在C(而不是C++)中实现编译时静态断言的最佳方法是什么,特别强调GCC?
我喜欢提供有用的错误/消息,我也想为我static_assert的.问题是,它们依赖于模板参数.通常情况下,由于引发的错误,这些参数会在途中或其他参数上显示,但它们要么模糊不清,要么不分组,因此它们有意义.例:
template<class T>
struct fake_dependency{
static bool const value = false;
};
template<class T, class Tag>
struct Foo{
Foo(){}
template<class OtherTag>
Foo(Foo<T, OtherTag> const&){
static_assert(fake_dependency<T>::value, "Cannot create Foo<T,Tag> from Foo<T,OtherTag>.");
}
};
int main(){
Foo<int, struct TagA> fA;
Foo<int, struct TagB> fB(fA);
}
Run Code Online (Sandbox Code Playgroud)
MSVC上的输出:
src\main.cpp(74): error C2338: Cannot create Foo<T,Tag> from Foo<T,OtherTag>.
src\main.cpp(84) : see reference to function template instantiation 'Foo<T,Tag>::Foo<main::TagA>(const Foo<T,main::TagA> &)' being compiled
with
[
T=int,
Tag=main::TagB
]
Run Code Online (Sandbox Code Playgroud)
函数模板本身提到了一个标记,下面是类模板.不太好.让我们看看海湾合作委员会的成果:
prog.cpp: In constructor 'Foo<T, Tag>::Foo(const …Run Code Online (Sandbox Code Playgroud) 如何static_assert在一个constexpr函数中正确执行?例如:
constexpr int do_something(int x)
{
static_assert(x > 0, "x must be > 0");
return x + 5;
}
Run Code Online (Sandbox Code Playgroud)
这不是有效的C++ 11代码,因为constexpr函数必须只包含return语句.我不认为该标准有例外,但GCC 4.7不允许我编译这段代码.
我想添加在编译期间检查结构大小的代码,以确保它是预定义的大小.例如,当我移植此代码或在编译期间添加/删除结构中的项时,我想确保此结构的大小为1024字节:
#pack(1)
struct mystruct
{
int item1;
int item2[100];
char item3[4];
char item5;
char padding[615];
}
Run Code Online (Sandbox Code Playgroud)
我知道如何在运行时使用如下代码执行此操作:
if(sizeof(mystruct) != 1024)
{
throw exception("Size is not correct");
}
Run Code Online (Sandbox Code Playgroud)
但如果我在运行期间这样做,那将浪费处理.我需要在编译期间执行此操作.
如何在编译期间执行此操作?
我使用g ++ 4.6.3(目前是ubuntu 12.04的默认包),标志为c ++ 0x,我偶然发现:
template <typename T>
inline T getValue(AnObject&)
{
static_assert(false , "this function has to be implemented for desired type");
}
Run Code Online (Sandbox Code Playgroud)
编译错误:
static_assertion failed "this function has to be implemented for the desired type"
Run Code Online (Sandbox Code Playgroud)
即使我还没有在任何地方调用此功能.
这是一个g ++错误吗?只有在代码中的某处调用此函数时,才应该实现此函数.
P0292R1 constexpr如果已包含在内,正在进行 C++ 17.它似乎很有用(并且可以取代SFINAE的使用),但关于static_assert形成不良的评论,假分支中不需要诊断会让我害怕:
Disarming static_assert declarations in the non-taken branch of a
constexpr if is not proposed.
void f() {
if constexpr (false)
static_assert(false); // ill-formed
}
template<class T>
void g() {
if constexpr (false)
static_assert(false); // ill-formed; no
// diagnostic required for template definition
}
Run Code Online (Sandbox Code Playgroud)
我认为它是完全禁止static_assert在constexpr内部使用if(至少是假/非分支,但实际上这意味着它不是一个安全或有用的事情).
这是如何从标准文本中产生的?我发现static_assert在提案中没有提到措辞,并且C++ 14 constexpr函数允许static_assert(cppreference的详细信息:constexpr).
是否隐藏在这个新句子中(6.4.1之后)?:
当constexpr if语句出现在模板化实体中时,在封闭模板或通用lambda的实例化期间,不会实例化丢弃的语句.
从那以后,我认为它也是禁止的,不需要诊断,调用调用图中某个地方可能调用的其他constexpr(模板)函数static_assert.
底线:
如果我的理解是正确的,那么对于constexpr …
#include <type_traits>
int main()
{
auto f1 = [](auto&) mutable {};
static_assert(std::is_invocable_v<decltype(f1), int&>); // ok
auto const f2 = [](auto&) {};
static_assert(std::is_invocable_v<decltype(f2), int&>); // ok
auto const f3 = [](auto&) mutable {};
static_assert(std::is_invocable_v<decltype(f3), int&>); // failed
}
Run Code Online (Sandbox Code Playgroud)
查看演示
为什么 const mutable lambda 不能采用引用参数?
我正在整理一些旧的代码,这些代码使用"幻数"来设置硬件寄存器,我想使用常量而不是这些数字来使代码更具表现力(实际上它们将映射到名称/用于记录寄存器的值).
但是,我担心随着变化的数量,我可能会打破神奇的数字.这是一个简化的例子(寄存器集更复杂):
const short mode0 = 0;
const short mode1 = 1;
const short mode2 = 2;
const short state0 = 0;
const short state1 = 4;
const short state2 = 8;
Run Code Online (Sandbox Code Playgroud)
而不是:
set_register(5);
Run Code Online (Sandbox Code Playgroud)
我们有:
set_register(state1|mode1);
Run Code Online (Sandbox Code Playgroud)
我正在寻找的是构建时间版本:
ASSERT(5==(state1|mode1));
Run Code Online (Sandbox Code Playgroud)
更新
@Christian,感谢快速响应,我对C/non-boost环境的答案感兴趣,因为这是驱动程序/内核代码.
我很遗憾地从我的库的原始版本中遗留了几个宏,这些宏使用了一些非常疯狂的C.特别是,我有一系列宏,希望将某些类型传递给它们.有可能做一些事情:
static_assert(decltype(retval) == bool);
Run Code Online (Sandbox Code Playgroud)
如何?有没有聪明的选择?
是的我知道宏很糟糕.我知道C++不是C等.
static-assert ×10
c++ ×8
c++11 ×4
assert ×3
c ×3
templates ×3
constexpr ×2
g++ ×2
c++17 ×1
c++20 ×1
compile-time ×1
debugging ×1
gcc ×1
lambda ×1
refactoring ×1
type-traits ×1