c++ - 子类作为模板基类的模板模板参数,而模板基类又是子类函数参数

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

以下代码

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.

但是派生 一个类模板。

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

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){}
};

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

第一个代码有什么问题?

如何让模板子类从模板基类继承,子类是基类的模板模板参数,并且子类中还有一个成员函数,该函数引用该基类作为参数?

最佳答案

第一个片段被 GCC 和 Clang 接受。请参阅here .

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

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

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

关于c++ - 子类作为模板基类的模板模板参数,而模板基类又是子类函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56190900/

相关文章:

C++定义一个函数当且仅当另一个函数不存在

C++11 和广义初始化器约定

c++ - std::bind pre-C++11 的替代方案

c++ - 如何在运行时查找 boost::fusion::vector 中的元素?

c++ - 如果没有提供 Container::value_type,如何获取 C++ Container<T> 的 T?

c++ - 模板模板模板参数是扩展还是标准的一部分?

c++ - 如何在 C++17 中强制模板和模板参数之间的约束

c++ - 防止在 C++ 中以错误的顺序将值传递给函数/构造函数

c++ - boost asio serial_port_service 和 serial_port 有什么区别

c++ - operator= in c++(11)工作方向