【问题标题】:Unable to compile class with a template parameter无法使用模板参数编译类
【发布时间】:2018-02-04 17:05:53
【问题描述】:

我有一些非常简单的代码,如下所示:

template <typename T, const T DEFAULT>
class One
{
    T *p;
};

template <typename T, const T DEFAULT>
class Two
{
    One<One<T, DEFAULT>, DEFAULT> *p;
};

当我尝试编译它时,我收到一条错误消息:

错误:'class One' 不是模板非类型参数的有效类型

但是,当我将 const T DEFAULT 更改为 typename T2 并将 DEFAULT 更改为 T2 时,它开始工作:

template <typename T, typename T2>
class One
{
    T *p;
};

template <typename T, typename T2>
class Two
{
    One<One<T, T2>, T2> *p;
};

但是,这不是我想要的。我需要我的第一个代码变体,但我不知道它有什么问题以及如何修复它。

【问题讨论】:

  • 只有像 intbool 这样的原始类型可以用作非类型模板参数。改为为 One 提供专业化。
  • 好吧,正如编译器告诉你的那样,你不能将One&lt;T, DEFAULT&gt; 类型用于非类型模板参数。您的第二个示例完全不同,因为它使用类型参数而不是非类型参数。
  • 除了One&lt;T, DEFAULT&gt; 不是非类型模板参数的有效类型之外,还有DEFAULT 不是 类型为One&lt;T, DEFAULT&gt; 的问题(如@ 987654335@ 需要)。这闻起来像 X/Y 问题。

标签: c++


【解决方案1】:
template <typename T, const T DEFAULT>
class One
{
    T *p;
};

template <typename T, const T DEFAULT>
class Two
{
    One<One<T, DEFAULT>, DEFAULT> *p;
};

这有几个问题:

  1. DEFAULTOne&lt;T, DEFAULT&gt; 的类型不同; DEFAULT 的类型为 T。因此你不能使用One&lt;One&lt;T, DEFAULT&gt;, DEFAULT&gt;

  2. 只有少数类型是valid as template non-type parameters。引用 cppreference:

    • std::nullptr_t(C++11 起);
    • 整体式;
    • 左值引用类型(对象或函数);
    • 指针类型(指向对象或函数);
    • 指向成员类型的指针(指向成员对象或成员函数);
    • 枚举类型。

One&lt;T, DEFAULT&gt;不是上述之一,所以不能作为模板非类型参数使用

【讨论】:

【解决方案2】:
template <typename T, const T DEFAULT>
class One

第二个T引用第一个,是非类型模板参数DEFAULT的类型。

例如,您可以像这样实例化One 模板:

One<int, 12345> // T is int, DEFAULT is 123456

或者像这样:

One<char, 100> // T is char, DEFAULT is 100

或者像这样:

One<int*, nullptr> // T is int*, DEFAULT is nullptr

这些示例的共同点是T 必须是有效的非类型模板参数。例如,您不能为其使用类型模板参数:

One<std::string, 123> // fails, because `std::string` cannot be used as `DEFAULT`

现在如果你看看你的第二节课......

template <typename T, const T DEFAULT>
class Two
{
    One<One<T, DEFAULT>, DEFAULT> *p;
};

One 的尝试外部实例化中,T 将是One&lt;T, DEFAULT&gt;。这与上面的std::string 示例完全相同; One&lt;T, DEFAULT&gt; 不是非类型模板参数。

对此没有“修复”,因为您的 Two 类的概念从根本上被打破了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    • 2020-01-21
    • 2013-12-09
    • 1970-01-01
    相关资源
    最近更新 更多