我有以下课程模板:
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
as:
template <int D1, int D2>
class Foo
{
char* arr;
};
我知道它不会以这种方式工作,因为模板参数对于所有3种情况都是相同的。我考虑过使用std::enable_if
或std::conditional
,但我不确定我是怎么做到的。任何人都可以帮助我吗?
答案 0 :(得分:2)
这应该有效:
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];
};
如果您不喜欢其他的默认模板参数,请将其放入详细命名空间,并将外部Foo
作为别名模板。
答案 1 :(得分:1)
我会在单独的命名空间中编写特化,并使用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的解决方案,以便在主类之外拥有专门的实现。例如。如果你还想根据相同的条件向类中添加更多的成员函数。
更新:请注意@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>>;