以下代码
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){}
};
表明错误消息具有误导性。
第一个代码有什么问题?
如何让模板子类继承自模板基类,而子类是基类的模板模板参数,又如何在子类中具有成员函数,该成员函数将对该基类的引用作为参数? / p>
答案 0 :(得分:3)
第一个代码段已被GCC和Clang接受。参见here。
我似乎记得MSVC有一个错误,它认为Derived
是指注入的类名,而不是模板名。但是,该标准非常清楚,当将封闭类的名称用作模板模板参数的参数时,应将其解释为模板([temp.local]/1),因此您的代码很好。
您使用的旧版Clang似乎有相同的错误。
作为一种解决方法,您可以编写::Derived
强制其查找模板名称,而不是注入的类名称。