考虑这个简化的实现std::any
(省略不相关的部分)和一些使用它的代码:
namespace std {
namespace details {
// Each instance of this function template has a different address
template <typename T>
const char *dummy_function() { return __PRETTY_FUNCTION__; }
template <typename T> void *construct(T &&);
void destroy(void *storage, const char *(*type_identifier)());
}
class any {
const char *(*type_identifier)();
void *storage;
public:
template <typename Arg>
any(Arg &&arg)
: type_identifier(&details::dummy_function<decay_t<Arg>>)
, storage(details::construct(forward<Arg>(arg))) {}
template <typename Arg>
any &operator=(Arg &&arg) {
details::destroy(storage, type_identifier);
type_identifier = &details::dummy_function<decay_t<Arg>>;
storage = details::construct(forward<Arg>(arg));
}
template <typename T>
friend T *any_cast(any *source) {
if (source && source->type_identifier == &dummy_function<T>)
return static_cast<T *>(source->storage);
return nullptr;
}
};
}
#include <any>
// Code that compares any::type_identifier a lot but never calls through it
std::any any = 42;
assert(std::any_cast<int>(&any) != nullptr);
assert(std::any_cast<double>(&any) == nullptr);
any = std::string("Hello");
assert(std::any_cast<std::string>(&any) != nullptr);
assert(std::any_cast<std::vector<char>>(&any) == nullptr);
如果优化编译器可以证明std::details::dummy_function<T>
在整个程序中从未以任何方式调用过,那么编译器是否允许在编译结果中不包含 any 的函数体std::details::dummy_function<T>
(以及由此未引用__PRETTY_FUNCTION__
的 s)T
(甚至可能使它们的地址任意指针大小的整数只能保证是不同的,否则甚至可能不是有效的内存地址)?
(或者甚至不能保证不同的地址是不同T
的,这很遗憾意味着我的实现一开始就不正确?)