std::addressof為什么當我明確指定型別時不能獲取地址?
更奇怪的是,當我從 cppreference 中 c/p 實作時,我可以獲取該函式的地址。
#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;
}
注意:我知道這樣做可能是非法的,因為函式是 in std::,但我關心語言/實作限制,而不是 UB,因為我在做一些邪惡的事情。
uj5u.com熱心網友回復:
正如您已經暗示過的那樣,獲取的地址std::addressof具有未指定的行為并且可能會或可能不會起作用,因為它在標準中未被指定為可尋址函式。
但更實際地說,問題在于至少有兩個多載std::addressof,它們都是帶有一個模板引數的模板。
一個T&作為函式引數,另一個const T&&作為函式引數(T模板引數在哪里)。后者被定義為洗掉。
std::addressof<int>不足以決定選擇哪一個。
庫實作還可以選擇以不同方式實作這些指定的多載或添加額外的多載,這就是未指定獲取地址的原因。
uj5u.com熱心網友回復:
除非它們是可尋址的函式,否則不應使用指向標準庫中函式的指標。
命名空間.std#6:
令 F 表示標準庫函式 ([global.functions])、標準庫靜態成員函式或標準庫函式模板的實體化。除非 F 被指定為可尋址函式,否則如果 C 程式顯式或隱式地嘗試形成指向 F 的指標,則它的行為是未指定的(可能是格式錯誤的)。
uj5u.com熱心網友回復:
您沒有像您在問題中宣告的那樣明確指定型別。您只提供一個模板引數。
嘗試實際明確指定型別:
int* (*fn_a)(int&) = &std::addressof<int>;
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/438899.html
