为什么我不能获取 std::addressof 函数的地址
Why I can't take address of the std::addressof function
为什么我在明确指定类型时无法获取 std::addressof
的地址?
为了让它更奇怪,当我 c/p 来自 cppreference I can take address of that function 的实现时
#include <memory>
template<typename T>
void templ_fn();
template<class T>
typename std::enable_if<std::is_object<T>::value, T*>::type xaddressof(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 xaddressof(T& arg) noexcept
{
return &arg;
}
int main() {
auto fn_1 = xaddressof<int>; // works
(void) fn_1;
auto fn_a = std::addressof<int>; // does not work
(void) fn_a;
}
注意:我知道这样做可能是非法的,因为函数在 std::
中,但我关心 language/implementation 限制,而不是 UB,因为我在做坏事。
正如您已经暗示过的那样,获取 std::addressof
的地址具有未指定的行为,因此可能会或可能不会工作,因为它未指定为 可寻址函数 在标准中。
但更实际地说,问题是 std::addressof
至少有两个重载,都是具有一个模板参数的模板。
一个以T&
作为函数参数,一个以const T&&
作为函数参数(其中T
为模板参数)。后者定义为delete
'd.
std::addressof<int>
不足以决定选择哪一个。
库实现还可以选择以不同的方式实现这些指定的重载,或者添加额外的重载,这就是获取地址未指定的原因。
您不应使用指向标准库中函数的指针,除非它们是可寻址函数。
Let F denote a standard library function ([global.functions]), a standard library static member function, or an instantiation of a standard library function template.
Unless F is designated an addressable function, the behavior of a C++ program is unspecified (possibly ill-formed) if it explicitly or implicitly attempts to form a pointer to F.
您没有像您在问题中声称的那样明确指定类型。您只提供了一个模板参数。
尝试明确指定类型:
int* (*fn_a)(int&) = &std::addressof<int>;
为什么我在明确指定类型时无法获取 std::addressof
的地址?
为了让它更奇怪,当我 c/p 来自 cppreference I can take address of that function 的实现时
#include <memory>
template<typename T>
void templ_fn();
template<class T>
typename std::enable_if<std::is_object<T>::value, T*>::type xaddressof(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 xaddressof(T& arg) noexcept
{
return &arg;
}
int main() {
auto fn_1 = xaddressof<int>; // works
(void) fn_1;
auto fn_a = std::addressof<int>; // does not work
(void) fn_a;
}
注意:我知道这样做可能是非法的,因为函数在 std::
中,但我关心 language/implementation 限制,而不是 UB,因为我在做坏事。
正如您已经暗示过的那样,获取 std::addressof
的地址具有未指定的行为,因此可能会或可能不会工作,因为它未指定为 可寻址函数 在标准中。
但更实际地说,问题是 std::addressof
至少有两个重载,都是具有一个模板参数的模板。
一个以T&
作为函数参数,一个以const T&&
作为函数参数(其中T
为模板参数)。后者定义为delete
'd.
std::addressof<int>
不足以决定选择哪一个。
库实现还可以选择以不同的方式实现这些指定的重载,或者添加额外的重载,这就是获取地址未指定的原因。
您不应使用指向标准库中函数的指针,除非它们是可寻址函数。
Let F denote a standard library function ([global.functions]), a standard library static member function, or an instantiation of a standard library function template. Unless F is designated an addressable function, the behavior of a C++ program is unspecified (possibly ill-formed) if it explicitly or implicitly attempts to form a pointer to F.
您没有像您在问题中声称的那样明确指定类型。您只提供了一个模板参数。
尝试明确指定类型:
int* (*fn_a)(int&) = &std::addressof<int>;