显式对象参数(Deducing This)结合完美转发实现向上转型的类型转换问题
C++显式对象参数结合完美转发的向上转型问题解答
1. static_cast<...>应填写的类型
你需要将&s转换为与s带相同cv限定的std::string*类型。可以通过std::pointer_traits的rebind特性简洁推导:
std::pointer_traits<decltype(&s)>::template rebind<std::string>
这个写法会自动匹配s的const/volatile属性:如果s是const A&,则推导为const std::string*;如果s是A&&,则推导为std::string*,完全符合转型需求。
2. 你给出的冗长写法是否可行?
该写法是可行的,但完全没有必要。它通过std::declval和forward_like间接推导指针类型,逻辑绕弯且可读性极差,属于过度复杂的实现,不推荐使用。
3. 最优实现方式
利用C20的std::pointer_traits::rebind结合C23的std::forward_like,可以写出简洁且类型安全的代码:
#include <string> #include <variant> #include <memory> // 用于std::pointer_traits struct A : public std::string {}; struct B : public std::string {}; struct V : public std::variant<A, B> { auto&& get_string(this auto &&self) { return std::visit( [](auto &&s) { // 自动推导带cv限定的std::string指针类型 using StringPtr = std::pointer_traits<decltype(&s)>::template rebind<std::string>; // 转型后解引用,再按self的值类别转发 return std::forward_like<decltype(self)> (*static_cast<StringPtr>(&s)); }, std::forward<decltype(self)>(self)); } };
实现逻辑说明:
std::pointer_traits<decltype(&s)>::rebind<std::string>:自动将指向派生类(A/B)的指针类型,转换为指向基类(std::string)的同cv限定指针类型,避免手动处理const/volatile的冗余代码。std::forward_like<decltype(self)>:根据self的左值/右值属性,将解引用后的std::string左值转换为对应值类别的引用,完美保持转发语义。
内容的提问来源于stack exchange,提问作者phinz
相关产品推荐
相关产品推荐

