您可以使用断言来测试 C++ 中的类型定义吗?

发布于 2024-12-07 01:38:28 字数 543 浏览 0 评论 0 原文

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

聚苯乙烯 显然我想将其用于任何类型定义,这里仅使用 double 作为示例。该解决方案应该是跨平台兼容的并且与C++03兼容。

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

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

Can I use assert to enforce type definitions. Suppose there is a variable, double d, how can you use assert to assert that d is a double? If assert is not applicable (which I am betting isn't), is there another option? I am specifically looking to test for implicit type casting during debugging, while benefiting from the functionality of assert and #define NDEBUG.

P.S
Obviously I would want to use this for any type definition, just using double as an example here. The solution should be cross platform compatible and be compatible with C++03.

I like to add error checking to my class setters. For example, suppose there is a class, MyClass, with a private member variable, x:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

深海夜未眠 2024-12-14 01:38:28

这实际上是一个编译时检查,因此您应该为此使用静态断言。

这是一个使用 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>();
}

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

It's really a compile time check, so you should use static asserts for this.

Here is an example using boost's static asserts and type traits.

#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>();
}

I assume you mean in terms of a template anyway.

萌梦深 2024-12-14 01:38:28

您可以使用 type_info == 运算符="nofollow noreferrer">class 用于测试特定类型定义。

#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
}

或者借用另一个使用模板和 try/catch 的 SO 答案

#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;
    }
}

You can use the == operator defined in the type_info class to test for a specific type definition.

#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
}

Or borrowing from another SO answer using templates and try/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;
    }
}
无边思念无边月 2024-12-14 01:38:28

您应该能够使用 std::is_same 和使用 decltype 进行比较。您甚至可以使用 std::static_assert 将检查移至编译时。我已经在 libc++ 中看到过这种情况 :)

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

You should be able to compare using std::is_same and using decltype. You can even use std::static_assert to move the check to compile time. I've seen it happen in libc++ :)

Note these are C++11 features, so you'll need to have a compiler that supports decltype

毁梦 2024-12-14 01:38:28

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

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;
}

Given the current definition of the code, a way to check at compile time whether both are of the same type is:

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;
}
皇甫轩 2024-12-14 01:38:28

您可以创建一个模板函数,然后重载 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;
}

You can create a template function, then overload the argument type for double like this:

#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
}

That would give a run-time error. You can generate a compile time error by simply defining a function that takes a double reference:

void is_double(double&) { }

void MyClass::setX(double input)
{
  is_double(x); // assert x is double
  x = input;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文