【发布时间】:2021-07-23 19:20:22
【问题描述】:
我们在工作中玩一些代码高尔夫。目的是保留to_upper 的签名并将所有参数返回给上层。我的一位同事提出了这个 ~~ugly~~ 精彩的代码:
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
std::string operator+(std::string_view& a, int const& b) {
std::string res;
for (auto c : a) {
res += (c - b);
}
return (res);
}
struct Toto {
std::string data;
};
struct Result {
std::string a;
std::string b;
};
std::unique_ptr<Toto> to_upper(std::string_view input_a,
std::string_view input_b) {
auto* res = new Result;
res->a = (input_a + 32);
res->b = (input_b + 32);
auto* void_res = reinterpret_cast<void*>(res);
auto* toto_res = reinterpret_cast<Toto*>(void_res);
return std::unique_ptr<Toto>(toto_res);
}
int main() {
std::unique_ptr<Toto> unique_toto_res = to_upper("pizza", "ananas");
auto* toto_res = unique_toto_res.release();
auto* res = reinterpret_cast<Result*>(toto_res);
std::cout << res->a << std::endl;
std::cout << res->b << std::endl;
return 0;
}
这种使用reinterpret_cast 在可移植性和UB 方面是否合适?
我们认为这没关系,因为我们只是在类型上欺骗编译器,但也许我们遗漏了一些东西。
【问题讨论】:
-
我不明白你为什么需要这些演员表,从
Toto继承Result并使用dynamic_cast应该可以解决所有问题而不必担心 UB。 -
避免使用幻数:
'A' - 'a' -
@sklott 这样的解决方案不要求
Totobase 是一个多态类吗? (解决安全问题。) -
顺便说一句,
a-z不保证是连续的(EBCDIC 是一个反例)。所以'A' - 'a'不能保证等于'Z' - 'z'。 -
首先,
reinterpret_cast往返于void*基本上没有意义——usestatic_castinstead。
标签: c++ undefined-behavior reinterpret-cast