根据模板参数启用模板 Ctor
Enable Template Ctor based on template parameter
我得到了一个我一直在玩的简单 CRTP 模板 class,我想出了一个点,我需要有相同的 ctor,但本质上在构造函数初始化列表中做不同的事情。
我确实有替代解决方案,但我想知道是否可以通过更好的方式实现我想做的事情。
下面粘贴了 class 的精简版。
你可以忽略 Eigen 的东西它只是一个矩阵库。
template<class ImplT, size_t N, bool SquareMatrix = false>
class Foo
{
template<bool Test, typename Then, typename Else>
using conditional_t = typename std::conditional<Test, Then, Else>::type;
// this is defined at compile time so no need to init it
using VecN = Eigen::Matrix<double, N, 1>;
// this is a dynamic matrix so dimensions need to be specified at runtime
using MatN = Eigen::MatrixXd;
using MatrixType = conditional_t<SquarePreCovariance, MatN, VecN>;
inline ImplT& impl() noexcept { return static_cast<ImplT&>(*this); }
inline const ImplT& impl() const noexcept { return static_cast<const ImplT&>(*this); }
public:
// if SquareMatrix == false
Foo()
: parameters3(Matrix(N, N))
{}
// if SquareMatrix == true
Foo()
: parameters2(Matrix(N, N)),
parameters3(Matrix(N, N)),
{}
// easy solution that covers all cases
Foo()
: parameters3(Matrix(N, N)),
{
if (SquareMatrix)
parameters2.resize(N,N);
}
private:
VecN parameters;
MatrixType parameters2;
MatN parameters3;
};
有条件地委派构造函数怎么样?
private:
// if SquareMatrix == false
Foo(std::false_type)
: parameters3(Matrix(N, N))
{}
// if SquareMatrix == true
Foo(std::true_type)
: parameters2(Matrix(N, N)),
parameters3(Matrix(N, N))
{}
public:
Foo() : Foo(std::integral_constant<bool, SquareMatrix>{}) {}
构造函数可以模板化,只要所有模板参数都可以推导或具有默认值。
模板参数的替换失败导致它在重载解析期间被跳过。
必须注意明确两个构造函数版本是有效的重载,一个额外的虚拟模板参数可以解决这个问题。
#include <utility>
#include <iostream>
template <bool B>
struct S {
template <bool B_ = B, typename = typename std::enable_if<!B_>::type>
S() { std::cout << "1" << std::endl; }
template <bool B_ = B, typename = typename std::enable_if<B_>::type, typename = void>
S() { std::cout << "2" << std::endl; }
};
int main() {
S<false> sf; // okay, prints 1
S<true> st; // okay, prints 2
}
我得到了一个我一直在玩的简单 CRTP 模板 class,我想出了一个点,我需要有相同的 ctor,但本质上在构造函数初始化列表中做不同的事情。
我确实有替代解决方案,但我想知道是否可以通过更好的方式实现我想做的事情。
下面粘贴了 class 的精简版。 你可以忽略 Eigen 的东西它只是一个矩阵库。
template<class ImplT, size_t N, bool SquareMatrix = false>
class Foo
{
template<bool Test, typename Then, typename Else>
using conditional_t = typename std::conditional<Test, Then, Else>::type;
// this is defined at compile time so no need to init it
using VecN = Eigen::Matrix<double, N, 1>;
// this is a dynamic matrix so dimensions need to be specified at runtime
using MatN = Eigen::MatrixXd;
using MatrixType = conditional_t<SquarePreCovariance, MatN, VecN>;
inline ImplT& impl() noexcept { return static_cast<ImplT&>(*this); }
inline const ImplT& impl() const noexcept { return static_cast<const ImplT&>(*this); }
public:
// if SquareMatrix == false
Foo()
: parameters3(Matrix(N, N))
{}
// if SquareMatrix == true
Foo()
: parameters2(Matrix(N, N)),
parameters3(Matrix(N, N)),
{}
// easy solution that covers all cases
Foo()
: parameters3(Matrix(N, N)),
{
if (SquareMatrix)
parameters2.resize(N,N);
}
private:
VecN parameters;
MatrixType parameters2;
MatN parameters3;
};
有条件地委派构造函数怎么样?
private:
// if SquareMatrix == false
Foo(std::false_type)
: parameters3(Matrix(N, N))
{}
// if SquareMatrix == true
Foo(std::true_type)
: parameters2(Matrix(N, N)),
parameters3(Matrix(N, N))
{}
public:
Foo() : Foo(std::integral_constant<bool, SquareMatrix>{}) {}
构造函数可以模板化,只要所有模板参数都可以推导或具有默认值。
模板参数的替换失败导致它在重载解析期间被跳过。
必须注意明确两个构造函数版本是有效的重载,一个额外的虚拟模板参数可以解决这个问题。
#include <utility>
#include <iostream>
template <bool B>
struct S {
template <bool B_ = B, typename = typename std::enable_if<!B_>::type>
S() { std::cout << "1" << std::endl; }
template <bool B_ = B, typename = typename std::enable_if<B_>::type, typename = void>
S() { std::cout << "2" << std::endl; }
};
int main() {
S<false> sf; // okay, prints 1
S<true> st; // okay, prints 2
}