C++:替代"std::is_fundamental"?

c++: alternative to 'std::is_fundamental'?

本文关键字:fundamental std 替代 C++ is      更新时间:2023-10-16

在模板类中的函数中,我试图区分基本类型和其他类型。

在c++ 11中可以这样做:

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

如果我错了,请纠正我,这不仅仅是在c++ 11中。

在早期版本的c++中是否有替代方法?

你可以在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
}

使用这段代码您可能会遇到麻烦。如果您需要区分不同的类型特征,这必须在编译时完成,而不是在运行时。根据您执行的操作,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_fundamental切换到is_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重载,并且只有被选择的重载才会被实例化和编译。

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

编辑2:

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