c++ - 模板特化 : ‘Scalar’ does not name a type

标签 c++ templates c++11 c++14 template-specialization

我正在尝试为 complex 标量实现模板特化,并使用 the help of Stackoverflow ,开始使用 std::enable_if_t 及其穷人版本

#include <type_traits>
#include <complex>

// declarations
namespace Test {
  template<class Scalar>
    class A {
      public:
        A(const Scalar z);
        Scalar realPart();

      private:
        Scalar z_;
    };
}

// definitions
namespace Test {
  template<bool B, class T = void>
    using enable_if_t = typename std::enable_if<B,T>::type;
  template<class T> struct is_complex : std::false_type {};
  template<class T> struct is_complex<std::complex<T>> : std::true_type {};

  template<class Scalar>
    A<Scalar>::
    A(const Scalar z) : z_(z)
  { }

  template<class S = Scalar, enable_if_t<is_complex<S>{}>* = nullptr>
    Scalar
    A<Scalar>::realPart()
    {
      return z_.real();
    }

  template<class S = Scalar, enable_if_t<!is_complex<S>{}>* = nullptr>
    Scalar
    A<Scalar>::realPart()
    {
      return z_;
    }
}

int main() {
}

对于 C++11。然而,上述代码将声明和定义分开,无法编译

test4.cpp:29:22: error: ‘Scalar’ does not name a type
   template<class S = Scalar, enable_if_t<is_complex<S>{}>* = nullptr>
                      ^

我不清楚这是怎么失败的。有什么提示吗?

最佳答案

在这段代码中:

template<class S = Scalar, enable_if_t<is_complex<S>{}>* = nullptr>
Scalar A<Scalar>::realPart()
{
  return z_.real();
}

Scalar没有命名类型,因为它不是一个。那只是您一直在使用的模板参数的名称。你打算写的是:

template<class Scalar, enable_if_t<is_complex<Scalar>{}>* = nullptr>
Scalar A<Scalar>::realPart()
{
  return z_.real();
}

但是,这也行不通,因为 A没有第二个模板非类型参数,而您正试图将其传递给它。你真正想做的是部分特化成员函数 A<Scalar>::realPart()这在语言中是不可能的。

您需要做的是分派(dispatch)给知道该做什么的助手。像这样的东西:

template <class Scalar>
Scalar A<Scalar>::realPart() {
    return getRealPart(z_);
}

与:

template <typename Scalar>
Scalar getRealPart(Scalar r) { return r; }

template <typename Scalar>
Scalar getRealPart(std::complex<Scalar> c) { return c.real(); }

对于更复杂的类型特征,我们会做类似的事情:

template <class Scalar>
Scalar A<Scalar>::realPart() {
    return getRealPart(z_, is_complex<Scalar>{});
}

并且有重载 true_typefalse_type作为第二个参数。在这种特殊情况下,这是不必要的。

关于c++ - 模板特化 : ‘Scalar’ does not name a type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30740209/

相关文章:

c++ - 使用 boost 序列化到磁盘后无法加载回数据

c++ - 在模板本身中检索最里面的模板类型

c++ - 为什么必须在何处以及为什么要放置"template"和"typename"关键字?

c++ - 设计一个只能由特定类实例化的类(如果可能,通过 make_unique)

c++ - const 和 constexpr 数组之间的区别

c++ - 这是使用点积求两个 vector 之间角度的正确方法吗? C++ SFML

c++ - 如果我知道只使用现有元素,我可以在数组开头之前传递一个指针吗?

c++ - 在 C++ 中不调用构造函数

c++ - 重载模板函数选择(模式匹配)如何在 std::vector 插入中工作?

C++ access_once