布尔条件的模板专业化

Template specialization on boolean condition

我有以下 class 模板:

template <int D1, int D2>
class Foo;

对于所有 D1 >= 0 && D2 >= 0 我想将其专门化为:

template <int D1, int D2>
class Foo
{
    char arr[D1 * D2];
};

所有 D1 < 0 || D2 < 0 为:

template <int D1, int D2>
class Foo
{
    char* arr;
};

我知道它不会完全按照这种方式工作,因为所有 3 种情况的模板参数都相同。我考虑过使用 std::enable_ifstd::conditional,但我不确定该怎么做。谁能帮帮我?

这应该有效:

template <int D1, int D2, typename=void>
class Foo {
    char* arr;
};

template <int D1, int D2>
class Foo<D1, D2, std::enable_if_t<D1 >= 0 && D2 >= 0>>
{
    char arr[D1 * D2];
};

如果您不喜欢额外的默认模板参数,请将其放入 detail 命名空间并使外部 Foo 成为它的别名模板。

我会在单独的命名空间中编写专业化,并使用 std::conditional

从它们派生
#include <type_traits>

namespace detail {

template <int D1, int D2, int dummy = 0>
class Foo
{
    char arr[D1 * D2];
public:
    // define constructors
};

template <int D1, int D2>
class Foo<D1, D2, 1>
{
    char* arr;
public:
    // define constructors
};

}

template <int D1, int D2>
class Foo
:
    std::conditional_t<(D1>=0 && D2>=0), detail::Foo<D1,D2, 0>, detail::Foo<D1,D2, 1>>
{
public:
    using Foo::Foo; // inheriting constructors
};

我更喜欢这个而不是@JoachimPileborg 的解决方案,因为在主要 class 之外有专门的实现。例如。如果您还想根据相同条件向 class 添加更多成员函数。

更新:请注意,@Columbo 建议的修改后的解决方案避免使用继承构造函数(它甚至不适用于默认构造函数):

 template<int D1, int D2>
 using Foo = std::conditional_t<(D1>=0 && D2>=0), detail::Foo<D1,D2, 0>, detail::Foo<D1,D2, 1>>;