在1.43提升似乎BOOST_STATIC_ASSERT只允许放置一个布尔值,是否有一些替代方案允许我在编译错误上显示消息?
我从Sun C++ 5.10编译器那里得到一个关于我正在改变的一些现有代码中的隐藏虚拟方法的编译警告.无论出于何种原因,作者都没有为给定的数据类型实现函数的覆盖.我在这里重新创建了这种情况:
// First the data types
struct Shape {};
struct Square : public Shape {};
struct Circle : public Shape {};
struct Triangle : public Shape {};
// Now the visitor classes
struct Virtual
{
virtual ~Virtual() {}
virtual void visit( Square& obj ) {}
virtual void visit( Circle& obj ) {}
virtual void visit( Triangle& obj ) {}
};
struct Concrete : public Virtual
{
void visit( Square& obj ) {}
void visit( Circle& obj ) {} …Run Code Online (Sandbox Code Playgroud) 有一组宏,用于调试,记录,堆栈跟踪显示等.其中一个是:
#define ASSERT_IF_NULL_2(_ptr1, _ptr2) \
ASSERT(_ptr1); \
ASSERT(_ptr2);
Run Code Online (Sandbox Code Playgroud)
这是我编写的宏的简化版本.如果断言(运行时)失败,我有自定义断言对话框,将这种空检查失败记录到日志文件中.还编写了宏,以便在编译时检查非指针(static-assert).
现在,我正在寻找一些静态断言来检查两个指针是否实际相同.例:
int* ptr;
ASSERT_IF_NULL_2(ptr, ptr);
Run Code Online (Sandbox Code Playgroud)
应该引发编译器错误,因为宏的两个参数都是相同的.我不关心指针指向相同的内存(因为那是运行时).
我尝试过表达式:
int xx;
xx = 1 / (ptr-ptr);
xx = 1 / (&ptr - &ptr);
Run Code Online (Sandbox Code Playgroud)
它们都没有给出被零除编译器错误.另外,我尝试使用void*模板参数:
template<void* T>
class Sample{};
Run Code Online (Sandbox Code Playgroud)
但是它不允许将局部变量指针传递给模板非类型参数.
我使用的是VC9,它不支持constexpr关键字(甚至VS2012 也不支持).我尝试使用'const'代替,它不会抛出错误.我还将表达式用作数组大小,这总是会导致错误.
int array[(&ptr - &ptr)]; // Even with ptrdiff_t
Run Code Online (Sandbox Code Playgroud) 我有一个派生自A类的B类.A声明一个静态字段f,B可能声明一个相同名称的类似字段.以下不起作用:
struct A { static int f; };
struct B : A { static int f; }; // A::f is different from B::f
struct C : A {}; // A::f is the same as C::f
BOOST_STATIC_ASSERT((&A::f != &B::f));
BOOST_STATIC_ASSERT((&A::f == &C::f));
Run Code Online (Sandbox Code Playgroud)
尽管理论上这些断言可以在编译时检查,但是由于常量表达式不能接受地址,所以它们是不允许的.
有没有办法在编译时进行这种检查工作?
我一直在使用static_assert(以及标准化之前的变体).我相信我们很多人都会使用它的一个用途是确保敏感数据结构的大小保持在平台和配置之间.例如:
class SizeSensitiveClass
{
// ...
};
static_assert (sizeof(SizeSensitiveClass) == 18, "Check the size!");
Run Code Online (Sandbox Code Playgroud)
现在,我已经编写了一个方便的宏来帮助这个特殊用途:
#define STATIC_ASSERT_SIZE(T, sz) (sizeof(T) == (sz), "Size of '" #T "' doesn't match the expected value.")
Run Code Online (Sandbox Code Playgroud)
像这样使用:
STATIC_ASSERT_SIZE (SizeSensitiveClass, 18);
Run Code Online (Sandbox Code Playgroud)
产生此输出:(在编译时,显然,以编译错误的形式)
'SizeSensitiveClass'的大小与预期值不匹配.
这很好,但我想知道是否可以扩展此宏的实现(保持接口完整)以输出当前大小和数据结构的预期大小.理想情况下,输出应该类似于:
'SizeSensitiveClass'的大小与预期值不匹配(20对18).
即使是目前的尺寸也会非常方便.这可能吗?
我正在使用VC12(Visual C++ 2013)和GCC 4.8.1.我很感激任何可以移植到至少这两个的解决方案/技术/方法.
我应该提到我已经尝试过常见的"stringize"技巧,但它不起作用(正如人们所预料的那样.)它只是sizeof(T)在输出中生成文字字符串.
我有一个模糊的概念,这可能是使用constexprs(生成消息字符串)实现的,但我不熟悉它们.
有没有办法确定某些类型在编译期间是不可复制的?我需要以下:
template<typename T, unsigned long long MaxSize>
struct circular_buffer : boost::noncopyable {
static_assert(typeof(T) ?????, "T must be noncopyable!");
};
Run Code Online (Sandbox Code Playgroud) 有没有办法将模板函数的参数类型限制为仅指针或随机访问迭代器?
假设我正在开发一个仅适用于随机可访问容器的排序功能.我正在寻找一种方法来抛出编译时错误,如果用户通过非随机访问迭代器.
#include <type_traits>
#include <iterator>
template <class Iterator> void mySort(Iterator begin, Iterator end){
/*The below condition must be true if the 'Iterator' type is a pointer
or if it is of Category random_access_iterator_tag. How to make such check?*/
static_assert(some condition, "The mySort() function only accepts random access iterators or raw pointers to an array.\n");
for (Iterator it = begin; it != end; ++it){
/*Some kind of sorting is performed here, which
uses arithmetic operators + and - in the …Run Code Online (Sandbox Code Playgroud) 偶尔,我会将函数的返回值赋给auto类型的变量(例如auto returnValue = someFunction();),但仍希望澄清/强制执行关于该变量类型的某些假设 - 即它是类型的int.
虽然Concepts&type_traits提供了一些非常强大的静态假设验证功能,但它们不支持这样的内容:
static_assert( isType( returnValue, int ) );
//OR
static_assert( int == typeof( returnValue ) );
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
阅读hana的教程,我想知道如何static_assert按预期工作:
template <typename Any>
auto switch_(Any& a) {
return [&a](auto ...cases_) {
auto cases = hana::make_tuple(cases_...);
auto default_ = hana::find_if(cases, [](auto const& c) {
return hana::first(c) == hana::type_c<default_t>;
});
static_assert(default_ != hana::nothing,
"switch is missing a default_ case");
// ...
};
}
Run Code Online (Sandbox Code Playgroud)
文档明确声明default_不是constexpr对象,因此,即使operator!=这些类型的重载是constexpr函数,表达式default_ != hana::nothing也不能是常量表达式,因为它的一个参数不是.
教程说:
请注意我们如何在没有任何内容的情况下使用static_assert进行比较的结果,即使它
default_是一个非constexpr对象?大胆地说,Hana确保在运行时没有丢失编译时已知的信息,这显然是案例存在的default_情况.
教程在该段落中引用了什么,或者该表达式如何工作?
如果我static_assert在SFINAE的条件内使用,编译器会发出错误并停止.
template < int i>
class X
{
static_assert( i != 4 );
public:
static constexpr bool value = true;
};
template < typename T >
typename std::enable_if< T::value, void>::type Do( )
{
std::cout << "one" << std::endl;
}
template < typename T >
typename std::enable_if< !T::value, void>::type Do( )
{
std::cout << "two" << std::endl;
}
int main()
{
Do<std::true_type>();
Do<std::false_type>();
// ###########
Do<X<1>>();
Do<X<4>>();
}
Run Code Online (Sandbox Code Playgroud)
这是我们应该期待的行为吗?
c++ ×10
static-assert ×10
c++11 ×4
boost ×1
compile-time ×1
constexpr ×1
debugging ×1
noncopyable ×1
sfinae ×1
templates ×1
type-traits ×1
virtual ×1
visual-c++ ×1