【问题标题】:subclass as template template argument of template base class, which in turn is a subclass function parameter子类作为模板基类的模板模板参数,它又是子类函数参数
【发布时间】:2019-05-17 17:15:50
【问题描述】:

以下代码

template<template<typename, typename> class T, typename EKeyType, typename EValueType>
class Baseclass
{
};

template<typename EKeyType, typename EValueType>
class Derived : public Baseclass<Derived, EKeyType, EValueType>
{
public:
    void foo(const Baseclass<Derived, EKeyType, EValueType>& param){}
};

导致以下编译错误:

MSVC 14: error C3200: 'Derived<EKeyType,EValueType>': invalid template argument for template parameter 'T', expected a class template
clang 3.0.0: error: template argument for template template parameter must be a class template.

但是Derived类模板。

当我将代码更改为以下代码时,一切编译正常:

template<template<typename, typename> class T, typename EKeyType, typename EValueType>
class Baseclass
{
};

template<typename EKeyType, typename EValueType> class Derived;

template<typename EKeyType, typename EValueType>
class Derived2 : public Baseclass<Derived, EKeyType, EValueType>
{
public:
    void foo(const Baseclass<Derived, EKeyType, EValueType>& param){}
};

这表明错误信息具有误导性。

第一个代码有什么问题?

我怎样才能让模板子类继承自模板基类,子类是基类的模板模板参数,并且子类中还有一个成员函数,它以对该基类的引用作为参数?

【问题讨论】:

  • 您使用的是哪个版本的 clang 以及哪些标志?我无法重现此问题:godbolt.org/z/fl9aES
  • @MichaelKenzel:我刚刚检查了各种版本的clang,我可以在godbolt上用5.0.0之前的clang版本重现它,但我不能用5.0.0和更新的版本重现它铿锵声。
  • @MichaelKenzel 在复制代码中包含 foo 函数对于复制至关重要。您的链接中缺少它。
  • 啊,确实,对不起,我的错误。无论如何,您现在已经在下面得到了答案……

标签: c++ c++03 template-templates


【解决方案1】:

第一个 sn-p 被 GCC 和 Clang 接受。见here

我似乎记得 MSVC 有一个错误,它认为 Derived 指的是注入的类名,而不是模板名。但是,标准非常明确,当封闭类的名称用作模板模板参数的参数时,它应该被解释为模板([temp.local]/1),所以你的代码没问题。

看来您使用的旧版本 Clang 可能存在相同的错误。

作为一种解决方法,您可以编写::Derived 来强制它查找模板名称,而不是注入的类名称。

【讨论】:

  • 你是对的。 ::Derived 使 reprocase 工作,并且 MostInnerNamespace::Derived 相应地解决了当 Derived 位于一个或多个命名空间内时的问题。我可以使用早于 5.0.0 的 clang 版本在 Godbolt 上重现该问题,但我无法使用 5.0.0 和更新版本的 clang 重现该问题,因此您对旧版本 clang 的假设是正确的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-09
相关资源
最近更新 更多