【问题标题】:Is there a way to choose between different class implementations based on the type of the template argument?有没有办法根据模板参数的类型在不同的类实现之间进行选择?
【发布时间】:2019-07-13 11:08:52
【问题描述】:

例如,我想创建一个数组。数组接受要处理的类型作为模板参数。现在,如果类型是原始类型(int、double、short),则可以使用浅拷贝,而如果它是类,则需要使用类的复制构造函数。如果它是简单的方法之一,我可以在返回值上使用带有 std::enable_if 的 SFAINE,但构造函数并非如此。

我尝试了以下方法,但 GCC-9 给出了编译错误:

template< typename Type, typename std::enable_if< std::is_integral< Type >::value() >::type* = nullptr >
class Array
{
    ...Implementation...
}

template< typename Type, typename std::enable_if< std::is_integral< Type >::value() == false >::type* = nullptr >
class Array
{
    ...Implementation 2...
}

此外,我尝试了默认构造函数,但 GCC-9 仍然不满意:

template< typename Type >
class Array
{

    Array( typename std::enable_if< std::is_integral< Type >::value() >::type* = nullptr )
    {}

    Array( typename std::enable_if< std::is_integral< Type >::value() == false >::type* = nullptr )
    {}

}

有没有办法根据给定的模板参数的类型创建具有不同实现的同名类?

似乎有类似的问题,但我认为不完全是,如果我错了告诉我,我会删除问题

【问题讨论】:

  • 如何使用专业化?还是只是简单的重载?
  • 我可以专注于原始类型,因为没有太多,你说得对。想也许有人会知道一些一般的方法

标签: c++ templates


【解决方案1】:

借助 SFINAE 进行专业化的方法是为此提供一个模板参数:

template<typename Type, typename Enabler = void> class Array;

template<typename Type>
class Array<Type, typename std::enable_if<std::is_integral< Type >::value() >::type>
{
    // ...Implementation 1...
};

template<typename Type>
class Array<Type, typename std::enable_if<!std::is_integral< Type >::value() >::type>
{
    // ...Implementation 2...
};

【讨论】:

  • 是的!谢谢你,兄弟!!我想这是你第二次救我了!!
【解决方案2】:

您可以在方法中的常规 if 块中使用 is_integral。

#include <type_traits>

template <typename Type>
class Array
{
    // Implementation
}

template <typename Type>
Array::someMethod()
{
    if (std::is_integral<Type>::value)
    {
        // Your shallow copy
    }
    else
    {
        // Your copy constructor
    }
}

您也可以通过这种方式进行专业化:

template <typename Type>
Array::someMethod()
{
    // Your copy constructor
}

template <>
Array<int>::someMethod()
{
    // Your shallow copy
}

但是这样你就必须为你想要浅拷贝的每种类型创建一个额外的方法。为优化起见,您只能使用一种方法进行浅拷贝,而您的所有专门方法都将调用此浅拷贝方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    • 2017-09-11
    • 1970-01-01
    • 2016-05-31
    相关资源
    最近更新 更多