Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于模板参数启用模板选择器_C++_Templates_C++11 - Fatal编程技术网

C++ 基于模板参数启用模板选择器

C++ 基于模板参数启用模板选择器,c++,templates,c++11,C++,Templates,C++11,我得到了一个简单的CRTP模板类,我一直在玩这个类,我发现我需要有相同的ctor,但在构造函数初始化列表中基本上做不同的事情 我确实有一个替代方案,但我想知道我想做的事情是否能以更好的方式实现 该类的精简版本粘贴在下面。 你可以忽略特征值,它只是一个矩阵库 template<class ImplT, size_t N, bool SquareMatrix = false> class Foo { template<bool Test, typename Then, type

我得到了一个简单的CRTP模板类,我一直在玩这个类,我发现我需要有相同的ctor,但在构造函数初始化列表中基本上做不同的事情

我确实有一个替代方案,但我想知道我想做的事情是否能以更好的方式实现

该类的精简版本粘贴在下面。 你可以忽略特征值,它只是一个矩阵库

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
}

我想你必须专攻这两种情况。这通常会生成大量样板代码,因此您可以利用C++11的构造函数继承特性使其更加优雅。没有经过测试,所以我希望我说的有道理。编辑:算了吧,到目前为止答案要好得多。标记分派>专门化通常+1标记分派TD与SFINAE与简单if和调整矩阵大小对性能的影响是什么,考虑到我可能只有2到init。我可以理解,如果我愿意先构建矩阵,然后调整矩阵的大小,而在其他情况下,我可以跳过这一步,那么TD的实施成本呢?我认为SFINAE在做我想做的事情方面将是最好的,除了由于两个因素造成的一些重复。我可以看到简单if在调试中生成了较小的汇编代码,但这就是我所能说的。我错过了你的回答,你有什么有趣的观点吗o@Columbo不,只是你的方法会奏效,但当你发表评论时,我已经在研究另一种方法了@hvd这种方法与Columbo的方法同样有效,除了许多关于多个定义的默认构造函数的编译器警告消息之外。实际上,每个派生类都有多个警告。了解dummy template参数肯定很有趣。@Xeron gcc和clang没有给出任何警告,这就是我在测试中使用的,但我现在看到VC++确实给出了警告。它真的不应该,代码是完全有效的,警告的文档甚至与实际的编译器行为不匹配:这是不正确的,即使在VC++上,第二个构造函数也被正确地调用。您可以在整个项目范围内抑制警告,但现在使用Columbo的答案更容易了。@hvd这就是我所做的,但只针对该头文件,而且效果很好。我不想在整个项目范围内做这件事。