gpt4 book ai didi

c++ - std::visit 不接受作为派生类对象的可调用对象

转载 作者:行者123 更新时间:2023-12-05 01:22:20 26 4
gpt4 key购买 nike

我正在尝试使用 std::visit 来检查 std::variant
首先,我声明变体和变体的基(可调用)访问者类:

#include <iostream>
#include <string>
#include <variant>


using Amalgamation = std::variant<int, bool, std::string>;

class BaseVisitor {
public:
virtual void operator()(int) {}
virtual void operator()(bool) {}
virtual void operator()(const std::string&) {}
};

其次,我定义了另一个派生自上述基类的访问者类:

class CheckBooleanVisitor
: public BaseVisitor {
public:
CheckBooleanVisitor()
: m_isBoolean(false) {
}

virtual void operator()(bool) override { // WHERE THE OVERRIDING TAKES PLACE
m_isBoolean = true;
}

bool isBoolean() const {
return m_isBoolean;
}
};

我使用这个“派生的”访问者类来访问这样的变体:

int main() {
Amalgamation a(0);
Amalgamation b(false);
CheckBooleanVisitor c;
std::visit(c, a); // LINE #1
std::cout << "a is " << (c.isBoolean() ? "" : "not ") << "a boolean." << std::endl;
std::visit(c, b); // LINE #2
std::cout << "b is " << (c.isBoolean() ? "" : "not ") << "a boolean." << std::endl;
return 0;
}

编译器 (VS 2022) 在 LINE #1LINE #2 中报错如下:
没有函数模板“std::visit”的实例匹配参数列表

但是,如果我尝试:

    std::visit((BaseVisitor&)c, a); // LINE #1
std::visit((BaseVisitor&)c, b); // LINE #2

程序按预期输出:

a is not a boolean.
b is a boolean.

另外,如果我给 std::visit 一个 BaseVisitor 的实例,不会发生错误。

为什么派生类 CheckBooleanVisitor 的对象不被接受为 std::visit 的有效可调用对象?
P/s:我很确定问题的原因是上面 CheckBooleanVisitor 定义中的代码。但是为什么?

最佳答案

函数重载(同一范围内的多个同名函数)和函数覆盖(派生类中的函数提供与 virtual 基类版本不同的实现)以不愉快的方式交互.

如果基类定义了一个具有某个名称的函数,而派生类定义了一个具有相同名称的函数,则派生类将默认隐藏基类版本的所有重载operator() 也不异常(exception)。基类版本不是派生类覆盖虚拟函数。

因此,如果您希望通过派生类实例访问未覆盖的版本,您必须显式地使用它们:

    virtual void operator()(bool) override { // WHERE THE OVERRIDING TAKES PLACE
m_isBoolean = true;
}

using BaseVisitor::operator();

关于c++ - std::visit 不接受作为派生类对象的可调用对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74337532/

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