W przypadku następującego kodu wszystkie twierdzenia oprócz ostatniego są przekazywane:
template<typename T>
constexpr void assert_static_cast_identity() {
using T_cast = decltype(static_cast<T>(std::declval<T>()));
static_assert(std::is_same_v<T_cast, T>);
}
int main() {
assert_static_cast_identity<int>();
assert_static_cast_identity<int&>();
assert_static_cast_identity<int&&>();
// assert_static_cast_identity<int(int)>(); // illegal cast
assert_static_cast_identity<int (&)(int)>();
assert_static_cast_identity<int (&&)(int)>(); // static assert fails
}
Dlaczego to ostatnie stwierdzenie zawodzi i static_cast<T>
nie zawsze zwraca a T
?
c++
static-cast
Eric
źródło
źródło
T_cast i{1};
, rozumieminvalid initialization of non-const reference of type 'T_cast' {aka 'int (&)(int)'} from an rvalue of type '<brace-enclosed initializer list>'
, więc z jakiegokolwiek powoduT_cast
jestint (&)(int)
raczej niżint (&&)(int)
.Odpowiedzi:
Jest to zapisane w definicji
static_cast
:decltype
szanuje kategorię wartości swojego argumentu i tworzy odwołanie do wartości dla wyrażeń wartości.Rozumowanie może wynikać z tego, że same nazwy funkcji zawsze są wartościami, dlatego wartość typu funkcji nie może pojawić się „na wolności”. Jako takie, rzutowanie na ten typ prawdopodobnie nie ma sensu.
źródło