gpt4 book ai didi

c++ - 具有重载方法的可变数据结构

转载 作者:太空狗 更新时间:2023-10-29 20:51:16 25 4
gpt4 key购买 nike

我有一个系统,其中包含许多可以发布/订阅的消息类型。添加新类型时,必须更新大量文件以添加对新方法类型的支持。

是否可以将具有重载纯虚方法的 C++ 类声明为可变数据结构?

编译下面的 C++ 程序时,类型“MessageB”的第二个发布方法的声明被“MessageA”的声明隐藏。

main.cpp:57:41: error: no matching function for call to ‘IPublisher::publish(MessageB)’ publisher->publish(MessageB{"world"});

这与 GCC 和 Clang 一致,但 Clang 确实会发出有用的警告:

warning: 'IPublishOne::publish' hides overloaded virtual function [-Woverloaded-virtual] virtual void publish(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;
}

最佳答案

Why would method hiding occur since MessageA and MessageB are distinct types?

您缺少最终覆盖

IPublishOne<T, Ts...>::publish 覆盖 IPublishOne<T>::publish根据 class.virtual/2 :

If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list, cv-qualification, and ref-qualifier (or absence of same) as Base​::​vf is declared, then Derived​::​vf is also virtual (whether or not it is so declared) and it overrides Base​::​vf.

您需要的是 final overrider :

struct IPublishOne<T, Ts...> 中指定最终覆盖 :

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

关于c++ - 具有重载方法的可变数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50938275/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com