有没有办法根据模板参数的类型在不同的类实现之间进行选择?

问题描述 投票:0回答:2

例如,我想创建一个数组。该数组接受要处理的类型作为模板参数。现在,如果类型是原始类型(int、double、short),则可以使用浅复制,而如果是类,则需要使用该类的复制构造函数。如果它是其中一种方法,那就很容易了,我可以在返回值上使用 SFAINE 和 std::enable_if ,但构造函数并非如此。

我尝试了以下方法,但 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
2个回答
4
投票

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...
};

由于概念/约束,C++20 允许在没有额外模板参数的情况下进行专门化:

template <typename Type> class Array;

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

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

2
投票

您可以在方法内部的常规

is_integral
块中使用
if

#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
}

但是这样你就必须为你想要浅复制的每种类型创建一个额外的方法。为了优化,您只能使用一种方法进行浅复制,并且所有专用方法都将调用此浅复制方法。

© www.soinside.com 2019 - 2024. All rights reserved.