C++ 具有重载方法的可变数据结构
我有一个可以发布/订阅多种消息类型的系统。添加新类型时,必须更新大量文件以添加对新方法类型的支持C++ 具有重载方法的可变数据结构,c++,c++11,templates,variadic-templates,overloading,C++,C++11,Templates,Variadic Templates,Overloading,我有一个可以发布/订阅多种消息类型的系统。添加新类型时,必须更新大量文件以添加对新方法类型的支持 是否可以用一个泛型的纯虚方法声明一个C++类作为一个可变数据结构?< /P> 编译C++程序时,“ MessageB >第二种发布方法的声明被“ MessageA < /代码>”所隐藏。 main.cpp:57:41:错误:调用'ippublisher::publish(MessageB)'publisher->publish(MessageB{“world”}没有匹配的函数 这与GCC和Clan
是否可以用一个泛型的纯虚方法声明一个C++类作为一个可变数据结构?< /P>
编译C++程序时,“<代码> MessageB <代码> >第二种发布方法的声明被“<代码> MessageA < /代码>”所隐藏。 main.cpp:57:41:错误:调用'ippublisher::publish(MessageB)'publisher->publish(MessageB{“world”}没有匹配的函数
这与GCC和Clang一致,但Clang确实发出了有用的警告: 警告:“IPublishOne::publish”隐藏重载虚拟函数[-Woverloaded virtual]虚拟无效发布(const T&message)=0 既然MessageA和MessageB是不同的类型,为什么会发生方法隐藏#include <iostream>
#include <memory>
using namespace std;
template <class...Ts>
struct IPublishOne;
template <class T>
struct IPublishOne<T>
{
virtual void publish(const T& message) = 0;
};
template <class T, class... Ts>
struct IPublishOne<T, Ts...> : IPublishOne<Ts...>
{
virtual void publish(const T& message) = 0;
};
struct MessageA
{
std::string value;
};
struct MessageB
{
std::string value;
};
struct IPublisher : public IPublishOne<MessageA, MessageB>
{
virtual ~IPublisher() = default;
};
struct Publisher : public IPublisher
{
void publish(const MessageA& message) override
{
std::cout << message.value << std::endl;
}
void publish(const MessageB& message) override
{
std::cout << message.value << std::endl;
}
};
int main()
{
const std::unique_ptr<IPublisher> publisher = std::make_unique<Publisher>();
publisher->publish(MessageA{"hello"});
// this produces compile error
publisher->publish(MessageB{"world"});
return 0;
}
#包括
#包括
使用名称空间std;
模板
结构IPublishOne;
模板
结构IPublishOne
{
虚拟无效发布(const T&message)=0;
};
模板
结构IPublishOne:IPublishOne
{
虚拟无效发布(const T&message)=0;
};
结构消息
{
std::字符串值;
};
结构消息B
{
std::字符串值;
};
结构IPPublisher:公共IPPublishOne
{
virtual~IPublisher()=默认值;
};
结构发布者:公共IPpublisher
{
无效发布(const MessageA&message)覆盖
{
std::cout问题在于在类中定义publish()
方法会隐藏从基类继承的所有publish()
方法
在IPublishOne
template <class T, class... Ts>
struct IPublishOne<T, Ts...> : IPublishOne<Ts...>
{
using IPublishOne<Ts...>::publish; // <<<-------------
virtual void publish(const T& message) = 0;
};
模板
结构IPublishOne:IPublishOne
{
使用IPublishOne::publish;//
既然MessageA和MessageB是不同的,为什么会发生方法隐藏
类型
您缺少最终覆盖器
IPublishOne::publish
覆盖IPublishOne::publish
依据:
如果虚拟成员函数vf
在类基中声明,并且在
类派生
,直接或间接派生自基
,成员
功能vf
具有相同名称、参数类型列表、cv鉴定、,
和ref限定符(或缺少相同的限定符)作为Base::声明vf
,然后
派生::vf
也是虚拟的(无论是否如此声明),并且
它覆盖Base::vf
您需要的是:
在结构IPublishOne
中指定最终重写器:
模板
结构IPublishOne:IPublishOne
{
使用IPublishOne::publish;//的最终重写器
//IPublishOne::发布
虚拟无效发布(const T&message)=0;
};
如果它没有编译,最好让我们也知道错误消息,而不仅仅是警告。为后代编辑,在GCC上添加编译错误。干杯。
template <class T, class... Ts>
struct IPublishOne<T, Ts...> : IPublishOne<Ts...>
{
using IPublishOne<Ts...>::publish; // final overrider for
// IPublishOne<T>::publish
virtual void publish(const T& message) = 0;
};