在模板类中生成无效数据类型的编译时错误? [英] Generating compile time errors for invalid data types in a template class?

查看:133
本文介绍了在模板类中生成无效数据类型的编译时错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用C ++来创建一个字符串类。我希望类只接受char和wchar_t的数据类型,我希望编译器在编译时使用#error来捕获任何无效的数据类型。我不喜欢使用assert()。我该怎么做?

解决方案

可以使用静态断言。提高提供一个



也许像:

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

模板< typename T>
class my_string
{
public:
// ...
private:
BOOST_STATIC_ASSERT((boost :: is_same< T,char> ::值||
boost :: is_same< T,wchar_t> :: value));
};

int main(void)
{
my_string< char> chstr;
my_string< wchar_t> WSTR;

// failed
my_string< int> ISTR;
}

如果您不能使用Boost,您可以轻松地重新设置静态断言和 is_same

  //静态断言失败
模板< ; bool谓词>
struct STATIC_ASSERT_FAILURE;

template<>
struct STATIC_ASSERT_FAILURE< true> {}; //只有true定义

//静态assert测试
模板< unsigned TestResult>
struct static_assert {};

//静态assert宏
#define STATIC_ASSERT(x)typedef static_assert< \
sizeof(STATIC_ASSERT_FAILURE<(x)>)> \
_static_assert_test_

//如果T和U是相同的类型,则值为true
template< typename T,typename U>
struct is_same
{
static const bool value = false;
};

模板< typename T>
struct is_same< T,T>
{
static const bool value = true;
};

模板< typename T>
class my_string
{
public:
// ...
private:
STATIC_ASSERT((is_same< T,char> :: value || is_same< T,wchar_t> :: value));
};

int main(void)
{
my_string< char> chstr;
my_string< wchar_t> WSTR;

// failed
my_string< int> ISTR;
}

注意,如果在同一个命名空间中使用静态assert两次,会得到一个名字碰撞。您必须使用更复杂的版本,使用诸如 __ COUNTER __ 之类的宏来生成唯一的名称。



以上工作在GCC 4.4和Visual Studio 2008中。


I am using C++ to create a string class. I want the class to only accept the data types char and wchar_t and I want the compiler to catch any invalid data types during compile time using #error. I do not like using assert( ). How can I do this?

解决方案

You can use a static assert. Boost provides one.

Maybe something like:

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

template <typename T>
class my_string
{
public:
    // ...
private:
    BOOST_STATIC_ASSERT((boost::is_same<T, char>::value ||
                          boost::is_same<T, wchar_t>::value));
};

int main(void)
{
    my_string<char> chstr;
    my_string<wchar_t> wstr;

    // fails
    my_string<int> istr;
}

If you can't use Boost, you can easily remake static-assert and is_same:

// static assert failure
template <bool Predicate>
struct STATIC_ASSERT_FAILURE;

template <>
struct STATIC_ASSERT_FAILURE<true> {}; // only true is defined

// static assert test
template <unsigned TestResult>
struct static_assert {};

// static assert macro
#define STATIC_ASSERT(x) typedef static_assert< \
                          sizeof(STATIC_ASSERT_FAILURE<(x)>)> \
                          _static_assert_test_

// value is true if T and U are the same type
template <typename T, typename U>
struct is_same
{
    static const bool value = false;
};

template <typename T>
struct is_same<T, T>
{
    static const bool value = true;
};

template <typename T>
class my_string
{
public:
    // ...
private:
    STATIC_ASSERT((is_same<T, char>::value || is_same<T, wchar_t>::value));
};

int main(void)
{
    my_string<char> chstr;
    my_string<wchar_t> wstr;

    // fails
    my_string<int> istr;
}

Note, if you use a static assert in the same namespace twice, you'll get a name collision. You' have to use a more sophisticated version that uses a macro such as __COUNTER__ to generate unique names.

The above works in both GCC 4.4 and Visual Studio 2008.

这篇关于在模板类中生成无效数据类型的编译时错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆