gpt4 book ai didi

C++ Variant 访问重载函数

转载 作者:行者123 更新时间:2023-12-04 12:29:29 27 4
gpt4 key购买 nike

我想在一个变体上执行一个重载的函数。以下代码块有效并编译,但 visit调用似乎过于复杂。为什么我不能简单地写:

std::visit(&f, something);
工作版本和上下文:
#include <variant>
#include <string>
#include <iostream>
#include <functional>

struct A {
std::string name = "spencer";
};

struct B {
std::string type = "person";
};

struct C {
double age = 5;
};

void f(A a) {
std::cout << a.name << std::endl;
}

void f(B b) {
std::cout << b.type << std::endl;
}

void f(C c) {
std::cout << c.age << std::endl;
}


int main() {
std::variant<A, B, C> something{B{}};
std::visit([](auto&& x) {f(x);}, something);
}
有没有更简单的方法?

最佳答案

std::visit(&f, something);
这是无效的,因为 f不是一个单一的功能。 &f说“给我一个指向 f 的指针”。但是 f不是一回事;它的三个函数碰巧共享一个名称,具有三个单独的指针。
std::visit([](auto&& x) {f(x);}, something);
这将创建一个基于模板的闭包,该模​​板生成代码以在编译时进行分派(dispatch)。实际上,它就像我们一样工作
void f(A a) {
std::cout << a.name << std::endl;
}

void f(B b) {
std::cout << b.type << std::endl;
}

void f(C c) {
std::cout << c.age << std::endl;
}

struct F {
template<typename T>
void operator()(T x) {
f(x);
}
};

int main() {
std::variant<A, B, C> something{B{}};
std::visit(F(), something);
}
这将迫使 C++ 编译器在模板扩展期间产生类似
void f(A a) {
std::cout << a.name << std::endl;
}

void f(B b) {
std::cout << b.type << std::endl;
}

void f(C c) {
std::cout << c.age << std::endl;
}

struct F {
void operator()(A x) {
f(x);
}
void operator()(B x) {
f(x);
}
void operator()(C x) {
f(x);
}
};

int main() {
std::variant<A, B, C> something{B{}};
std::visit(F(), something);
}
如果要消除 lambda 包装器,则需要一个可以作为参数传递的可调用对象,而函数指针是不够的,因为函数指针不能进行重载解析。我们总是可以显式地创建一个仿函数对象。
struct F {
void operator()(A a) {
std::cout << a.name << std::endl;
}
void operator()(B b) {
std::cout << b.type << std::endl;
}
void operator()(C c) {
std::cout << c.age << std::endl;
}
};

int main() {
std::variant<A, B, C> something{B{}};
std::visit(F(), something);
}
您是否认为这种方法比以前的方法更清洁取决于您。一方面,它更像传统的 OOP 访问者模式,因为我们有一个对象进行访问。另一方面,如果我们可以传递一个函数的名称并让 C++ 理解我们的意思,那就太好了,但这要么需要 std::visit 的特殊 C++ 语法。或多方法形式的运行时调度。无论哪种方式,它都不太可能很快发生,或者根本不会发生。

关于C++ Variant 访问重载函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66961406/

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