你能用assert来测试C ++中的类型定义吗?

时间:2011-09-26 18:58:27

标签: c++ debugging casting assert

我可以使用assert来强制执行类型定义。假设有一个变量double d,你如何使用assert断言d是双精度?如果assert不适用(我打赌不是),还有其他选择吗?我特别希望在调试期间测试隐式类型转换,同时受益于assert#define NDEBUG的功能。

P.S 显然我想将它用于任何类型定义,这里只使用double作为示例。该解决方案应该是跨平台兼容的并且与C ++ 03兼容。

我喜欢将错误检查添加到我的类设置器中。例如,假设有一个类MyClass,它带有一个私有成员变量x:

void MyClass::setX(double input)
{
   // assert x is double
   x = input;
}

5 个答案:

答案 0 :(得分:7)

这实际上是一个编译时检查,所以你应该使用静态断言。

这是一个使用boost的静态断言和类型特征的例子。

#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>

template<typename T>
  void some_func() {
    BOOST_STATIC_ASSERT( (boost::is_same<double, T>::value) );
  }

TEST(type_check) {
  some_func<double>();
}

无论如何,我认为你的意思是模板。

答案 1 :(得分:3)

您可以使用== class中定义的type_info运算符来测试特定的类型定义。

#include <assert.h>
#include <iostream>
#include <typeinfo>

int main ()
{
    double a = 0;

    std::cout << typeid(a).name() << std::endl;

    assert(typeid(a)==typeid(double));
    assert(typeid(a)==typeid(int)); // FAIL
}

或者使用模板借用其他SO answer并尝试/ catch:

#include <assert.h>
#include <iostream>
#include <typeinfo>

template <typename X, typename A>
inline void Assert(A assertion)
{
    if( !assertion ) throw X();
}

#ifdef NDEBUG
    const bool CHECK_ASSERT = false;
#else
    const bool CHECK_ASSERT = true;
#endif

struct Wrong { };

int main ()
{
    double a = 0;

    std::cout << typeid(a).name() << std::endl;

    assert(typeid(a)==typeid(double));
    Assert<Wrong>(!CHECK_ASSERT || typeid(a)==typeid(double));
    try
    {
    //assert(typeid(a)==typeid(int)); // FAIL and Abort()
        Assert<Wrong>(!CHECK_ASSERT || typeid(a)==typeid(int)); // FALL
    }
    catch (Wrong)
    {
        std::cerr <<"Exception, not an int" <<std::endl;
    }
}

答案 2 :(得分:1)

您应该可以使用std::is_same和使用decltype进行比较。您甚至可以使用std::static_assert将检查移动到编译时。我在libc ++中看到它发生了:)

请注意这些是C ++ 11的功能,因此您需要一个支持decltype的编译器

答案 3 :(得分:1)

鉴于代码的当前定义,在编译时检查两者是否属于同一类型的方法是:

template< typename T, typename U >
void assert_same_type( T const&, U const& )
{
     int error[ sizeof( T ) ? -1 : -2 ]; // error array of negative size, dependent on T otherwise some implementations may cause an early error message even when they shouldn't
}

template< typename T >
void assert_same_type( T&, T& ){}

void MyClass::setX(double input)
{
   assert_same_type( x, input ); // If the fallback case is instantiated then a compile time error will arise of trying to declare an array of negative size.

   x = input;
}

答案 4 :(得分:0)

您可以创建模板函数,然后重载double的参数类型,如下所示:

#include <cassert>

template<class T>
bool is_double(T) { return false; }
bool is_double(double) { return true; }

int main() {
    int i = 1;
    double d = 3.14;
    assert( is_double(d) );
    assert( is_double(i) ); // fails
}

这会产生运行时错误。您可以通过简单地定义一个带有双引用的函数来生成编译时错误:

void is_double(double&) { }

void MyClass::setX(double input)
{
  is_double(x); // assert x is double
  x = input;
}