为模板化的特定情况添加构造函数 class
Adding a constructor for specific case of templated class
我正在实施模板化 class Vect<std::size_t N>
,一个 N double
的向量。通用构造函数采用 std::array<double, N> const&
数组,但我希望例如 N=2
有一个采用 2 double
的构造函数,以允许更轻的实例化。
我想到了一个效果很好的解决方案(见下文),但感觉有点脏。我已经了解了这里提出的许多问题及其答案,但我还没有找到非常适合我的问题的解决方案。
我还想为 Vect<2>
设置一个别名 Vect2D
,使用 typedef
或其他任何可以完成此工作的别名(例如,我下面的解决方案)。
这是我的一些代码 class Vect
:
template<std::size_t N> class Vect{
protected:
std::array<double,N> v;
public:
Vect(const std::array<double,N>& _v = {}): v(_v) {}
/* bunch of methods & operators */
};
这是我目前的解决方案:
class Vect2D : public Vect<2>{
public:
Vect2D(double x = 0, double y = 0): Vect({x,y}) {}
Vect2D(const Vect<2>& other): Vect(other){}
};
(我必须添加最后一行,因为虽然 Vect2D
是 而 Vect<2>
,Vect<2>
不是 a Vect2D
,所以当我在两个 Vect2D
之间使用运算符时,returned 对象的类型为 Vect<2>
,因此如果需要我将其转换回 Vect2D
最后一行,例如,如果函数的 return 类型是 Vect2D
,而我 return 是两个 Vect2D
之间的运算符的结果。它完成了工作,但这也是我觉得这个解决方案有点脏的部分原因。)
如果有人有好的解决方案,我将不胜感激,否则这没什么大不了的,因为我的解决方案无论如何都能满足我的要求。
如何避免完全 class 专业化和 SFINAE 仅在 N
为 2 时才启用双精度构造函数?
有点像
template <std::size_t M = N, std::enable_if_t<(M == 2), int> = 0>
Vect (double x = 0, double y = 0): v{x,y} {}
I'd also like to have an alias Vect2D
for Vect<2>
, either with a typedef
or anything else that does the job
使用 using
怎么样?
using Vect2D = Vect<2>;
以下是使用外部构造函数实现的完整编译示例。
#include <array>
#include <type_traits>
template <std::size_t N>
class Vect
{
protected:
std::array<double, N> v;
public:
Vect (std::array<double, N> const & v0 = {});
template <std::size_t M = N, std::enable_if_t<(M == 2), int> = 0>
Vect (double x = 0, double y = 0);
};
template <std::size_t N>
Vect<N>::Vect (std::array<double, N> const & v0) : v{v0}
{ }
template <std::size_t N>
template <std::size_t M, std::enable_if_t<(M == 2), int>>
Vect<N>::Vect (double x, double y) : v{x,y}
{ }
// explicit deduction guide
Vect (double, double) -> Vect<2u>;
int main()
{
Vect<2u> v2{1.0, 2.0}; // compile
Vect v2bis{1.0, 2.0}; // compile as Vect<2> (thanks to the deduction guide)
// Vect<3u> v3{1.0, 2.0}; // compilation error (no matching constructor)
}
我正在实施模板化 class Vect<std::size_t N>
,一个 N double
的向量。通用构造函数采用 std::array<double, N> const&
数组,但我希望例如 N=2
有一个采用 2 double
的构造函数,以允许更轻的实例化。
我想到了一个效果很好的解决方案(见下文),但感觉有点脏。我已经了解了这里提出的许多问题及其答案,但我还没有找到非常适合我的问题的解决方案。
我还想为 Vect<2>
设置一个别名 Vect2D
,使用 typedef
或其他任何可以完成此工作的别名(例如,我下面的解决方案)。
这是我的一些代码 class Vect
:
template<std::size_t N> class Vect{
protected:
std::array<double,N> v;
public:
Vect(const std::array<double,N>& _v = {}): v(_v) {}
/* bunch of methods & operators */
};
这是我目前的解决方案:
class Vect2D : public Vect<2>{
public:
Vect2D(double x = 0, double y = 0): Vect({x,y}) {}
Vect2D(const Vect<2>& other): Vect(other){}
};
(我必须添加最后一行,因为虽然 Vect2D
是 而 Vect<2>
,Vect<2>
不是 a Vect2D
,所以当我在两个 Vect2D
之间使用运算符时,returned 对象的类型为 Vect<2>
,因此如果需要我将其转换回 Vect2D
最后一行,例如,如果函数的 return 类型是 Vect2D
,而我 return 是两个 Vect2D
之间的运算符的结果。它完成了工作,但这也是我觉得这个解决方案有点脏的部分原因。)
如果有人有好的解决方案,我将不胜感激,否则这没什么大不了的,因为我的解决方案无论如何都能满足我的要求。
如何避免完全 class 专业化和 SFINAE 仅在 N
为 2 时才启用双精度构造函数?
有点像
template <std::size_t M = N, std::enable_if_t<(M == 2), int> = 0>
Vect (double x = 0, double y = 0): v{x,y} {}
I'd also like to have an alias
Vect2D
forVect<2>
, either with atypedef
or anything else that does the job
使用 using
怎么样?
using Vect2D = Vect<2>;
以下是使用外部构造函数实现的完整编译示例。
#include <array>
#include <type_traits>
template <std::size_t N>
class Vect
{
protected:
std::array<double, N> v;
public:
Vect (std::array<double, N> const & v0 = {});
template <std::size_t M = N, std::enable_if_t<(M == 2), int> = 0>
Vect (double x = 0, double y = 0);
};
template <std::size_t N>
Vect<N>::Vect (std::array<double, N> const & v0) : v{v0}
{ }
template <std::size_t N>
template <std::size_t M, std::enable_if_t<(M == 2), int>>
Vect<N>::Vect (double x, double y) : v{x,y}
{ }
// explicit deduction guide
Vect (double, double) -> Vect<2u>;
int main()
{
Vect<2u> v2{1.0, 2.0}; // compile
Vect v2bis{1.0, 2.0}; // compile as Vect<2> (thanks to the deduction guide)
// Vect<3u> v3{1.0, 2.0}; // compilation error (no matching constructor)
}