使用is_integral / BOOST_STATIC_ASSERT限制模板实例化

时间:2010-09-28 09:47:55

标签: c++ boost

我正在尝试实现一个自由​​运算符函数,以便将任意数据类型的值流式传输到某个容器类(DataVector)。
我为基本数据类型和我项目中使用的复杂数据类型的一些特殊化做了一个模板(例子只包括std :: string)。
为了确保模板不会与基本实现未正确处理的数据类型一起使用,我想使用类型特征(is_integral)来限制实例化。几次尝试将is_enabled is_integral嵌入到运算符的签名中失败了,我最终得到了下面示例中的实现show。

typedef std::vector<unsigned char> DataVector;

template<typename T>
DataVector& operator <<(DataVector& vecArchive, T dataToAppend)
{
    if (boost::is_integral<T>::value == true)
    {
        // ... do something
        return vecArchive;
    }
    BOOST_STATIC_ASSERT(false);
};

template<> inline
DataVector& operator << <string> (DataVector& vecArchive, string dataToAppend)
{
    // do something different
    return vecArchive;
};

问题是它不会编译,即使对于整数数据类型也是如此。我猜BOOST_STATIC_ASSERT不能用于条件表达式。怎么做到呢?任何帮助将不胜感激。

main()
{
    DataVector vecTel;
    vecTel << (int)5;  // ok
    vecTel << std::string("Hello World");  // ok
    vecTel << std::map(int, int)  // must fail
}

编译错误:

d:... \ TcpSerializable.h(52):错误C2027:使用未定义类型'boost :: STATIC_ASSERTION_FAILURE'         同         [             X =假         ]         。\ Telegram050.cpp(38):参见函数模板实例化'BasisKlassen :: DataVector&amp; BasisKlassen :: operator&lt;&lt;(BasisKlassen :: DataVector&amp;,T)'正在编译         同         [             T = INT         ]

2 个答案:

答案 0 :(得分:4)

我不是boost的专家,但从它看起来BOOST_STATIC_ASSERT(0)即使boost::is_integral<T>::value返回true(类似于所有其他正常函数)也会编译。因此,您会收到编译器错误(正如静态断言的条件返回false时所预期的那样)。要解决这个问题,最简单的方法是将函数更改为:

template<typename T>
DataVector& operator <<(DataVector& vecArchive, T dataToAppend)
{
    BOOST_STATIC_ASSERT(boost::is_integral<T>::value);
    // ... do something
    return vecArchive;

};

答案 1 :(得分:3)

如果你真的需要将某个实现限制为整数类型,你可以使用boost enable_if

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

// operator<< for integral types
template<typename T>
typename boost::enable_if< boost::is_integral<T>, DataVector& >::type
operator<<(DataVector& vecArchive, T dataToAppend) {
    // ... do something
    return vecArchive;
};

// different operator<< for std::string
DataVector& operator<<(DataVector &vecArchive, const std::string &dataToAppend) {
    return vecArchive;
}

如果您尝试使用非整数类型,则会得到通常的编译器错误,找不到匹配的operator<<