gcc 为什么std::addressof的正确实现需要编译器支持?

6g8kf2rb  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(113)

std::addressofhttps://en.cppreference.com/w/cpp/memory/addressof上的可能实现来看,它指出“std::addressof的正确实现需要编译器支持”。为什么会这样呢?
我在https://godbolt.org/z/vnzbs9aTG上试用了这个实现,它像预期的那样工作。

#include <iostream>
#include <string>
#include <type_traits>

template<class T>
typename std::enable_if<std::is_object<T>::value, T*>::type addressof_impl(T& arg) noexcept
{
    return reinterpret_cast<T*>(
               &const_cast<char&>(
                   reinterpret_cast<const volatile char&>(arg)));
}
 
template<class T>
typename std::enable_if<!std::is_object<T>::value, T*>::type addressof_impl(T& arg) noexcept
{
    return &arg;
}

struct Student {
    std::string name{};
    int age{};
};

int main() {
    Student s;
    std::cout << addressof_impl(s);
    return EXIT_SUCCESS;
}

字符串

wko9yo5t

wko9yo5t1#

std::addressof应该可以在常量表达式中使用。比如说

constexpr int test() {
    int x;
    *std::addressof(x) = 0;
    return x;
}

constexpr int j = test();

字符串
应该是有效的,但不会与您的实现。在您的实现中添加constexpr也不会有帮助,因为计算reinterpret_cast总是使表达式不符合常量表达式的条件。
此外,您还缺少已删除的const右值重载,以防止获取右值的地址。
以上内容自C17起适用。如果你要求的是C11,那么是的,这是C11的有效实现。如果您浏览cppreference页面上提供的标准库实现链接,您还将看到它们使用了C17之前的建议实现(的微小变化)。

相关问题