5

In a function within a template class, I'm trying to distinguish between primitive types and others.

In c++ 11 you can do:

if(std::is_fundamental<T>::value)
{
    // Treat it as a primitive
}
else
{
    //Treat it otherwise
}

Please correct me if I'm wrong and this is not only in c++ 11.

Is there an alternative to this in earlier versions of c++?

4

2 回答 2

8

您可以像这样在 C++03 中使用Boost 的类型特征:

#include  <boost/type_traits/is_fundamental.hpp>

...

if(boost::is_fundamental<T>::value)
{
    // Treat it as a primitive
}
else
{
    //Treat it otherwise
}

我想这也应该适用于 C++98。

于 2013-05-29T07:04:24.683 回答
2

使用此代码,您可能会遇到麻烦。如果您需要区分不同的类型特征,则必须在编译时完成,而不是在运行时完成。根据您正在执行的操作,您的两个分支之一if可能无法编译。所以最好转发到一个专门的函数:

void operation_impl(boost::true_type /*other params*/) {
  // Treat it is primitive 
}

void operation_impl(boost::false_type /*other params*/) {
  // Treat it otherwise
}

template<class T>
void operation(/* params*/) {
  operation_impl(boost::is_fundamental<T>::type() /*other params*/);
}

使用这种实现技术,只需要编译使用的分支(即正确)。

编辑:

以下是一些附加信息。这个问题的解决方案与模板的实例化有关。我从 切换is_fundamentalis_array以显示操作如何失败。

让我们从第一个例子开始:

template <class T>
void fun(T t) {
    if(boost::is_array<T>::value)
    {
        std::cout << "true" << std::endl;
    }
    else
    {
        std::cout << "false" << std::endl;
    }
}

void f(int i) {
    fun(i);
}

它将编译并运行,编译器将看到 if 语句的一个分支将被使用,并将另一个分支作为未使用的代码删除。

在我的第二个示例中,我将在使用数组操作的情况下做一些事情:

template<class T>
void fun(T& t) {
    if(boost::is_array<T>::value)
    {
        std::cout << t[0];
    }
    else
    {
        std::cout << t;
    }
}

void f(int i) {
    fun(i);
}

现在它不会编译。原因是 int 作为模板参数t[0]格式不正确。您不能在编译时使用此运行时语句来区分代码中需要的类型属性(在本例中是数组的属性和 的使用t[0])。

在第三个示例中,我们将通过函数重载来区分编译时间:

template<class T>
void fun_impl(boost::true_type, T& t) {
    std::cout << t[0];
}

template<class T>
void fun_impl(boost::false_type, T& t) {
    std::cout << t;
}

template<class T>
void fun(T& t) {
    fun_impl(typename boost::is_array<T>::type(),t);
}

void f(int i) {
    fun(i);
}

这里is_array<T>::typetrue_typefalse_type。这个结果被用作fun_impl在编译时选择正确的重载的选择器,并且只有选择的重载被实例化和编译。

通常,此类技术用于在编译时选择最佳实现,该实现可能仅在类型具有某些属性时才可编译。

第二次编辑:

static if如果是语言的一部分,这当然会改变。

于 2013-05-29T10:46:11.143 回答