我想要函数重载,函数接受 boost::any 左值和 boost::any 右值作为参数,并基于此表现出不同的行为。最小可重复示例;
#include <boost/any.hpp>
#include <iostream>
#include <string>
#include <memory>
class MyClass {
public:
MyClass() {
a_int = -1;
b_string = "abc";
}
private:
int a_int;
std::string b_string;
public:
static void DumpMyClass(boost::any&& my_class_obj) {
std::cout << "rvalue reference" << std::endl;
}
static void DumpMyClass(const boost::any& my_class_obj) {
std::cout << "lvalue reference" << std::endl;
}
};
int main() {
std::shared_ptr<MyClass> c_sptr = std::make_shared<MyClass>();
MyClass::DumpMyClass(c_sptr);
MyClass::DumpMyClass(std::move(c_sptr));
return 0;
}
我看到的输出是这样的;
$clang++ -std=c++11 any.cc -o code && ./code
rvalue reference
rvalue reference
我希望调用 MyClass::DumpMyClass(c_sptr);会使用打印“左值引用”的函数。如果我将函数签名更改为具有
std::shared_ptr<MyClass>&
和 std::shared_ptr<MyClass>&&
类型的参数,而不是分别是 boost::any&
和 boost::any&& ,则行为符合预期。根据预期,我的意思是这种情况下的输出是
lvalue reference
rvalue reference
这里的问题是为什么它不能区分 boost::any 类型的左值和右值引用,而 std::shared_ptr 却可以区分?
我经历了this答案,它解释了重载解析的“更好匹配”,但我不太确定为什么它不适用于 boost::any ,更重要的是考虑到它适用于 std::shared_ptr 。
版本:clang 版本 3.4.2,boost 1.53,还检查了 boost 1.82。
问题不在于 boost::any,而在于存在从 std::shared_ptr 到 boost::any 的隐式转换。当将整数传递给接受双精度数的函数时,我们得到相同的效果:
#include <print>
void f(double&& d) {
std::println("rvalue reference");
}
void f(const double& d) {
std::println("lvalue reference");
}
int main() {
double d = 1.0;
f(d); // lvalue reference
f(std::move(d)); // rvalue reference
int n = 1;
f(n); // rvalue reference
f(std::move(n)); // rvalue reference
}