Как проверить, является ли конструктор копирования исключением без использования type_traits?

После некоторых экспериментов мне удалось написать фрагмент кода, который будет проверять, является ли конструктор перемещения класса noexcept (без использования type_traits; это просто упражнение):

std::cout << std::boolalpha << noexcept(Widget(std::declval<Widget>())) << std::endl;

Функция declval "возвращает" Widget&&, поэтому все выражение представляет собой вызов конструктора перемещения. Но как добиться чего-то подобного для конструктора копирования?


person rubix_addict    schedule 09.04.2015    source источник
comment
ты мог бы *static_cast<Widget>(nullptr)   -  person Walter    schedule 09.04.2015


Ответы (2)


Используйте 1_. Свертывание ссылки превратит T&& & в T&:

std::cout << std::boolalpha << noexcept(Widget(std::declval<Widget&>())) << std::endl;
//                                                          ^^^^^^^^
person 0x499602D2    schedule 09.04.2015
comment
Да и вообще, интересно, как написать подобную проверку для оператора copy=? :) - person BarbedWire; 16.11.2017
comment
@BarbedWire noexcept(declval<Widget&>() = declval<Widget const&>()) - person 0x499602D2; 16.11.2017

Вы можете объявить свою собственную declval-подобную функцию:

template< class T >
typename std::add_lvalue_reference<T>::type mydeclval() noexcept;

//outputs true if the copy constructor is declared noexcept
std::cout << std::boolalpha << noexcept(Widget(mydeclval<Widget>())) << std::endl;
person TartanLlama    schedule 09.04.2015
comment
О, я только что делал почти то же самое, но забыл добавить noexcept к самому mydeclval и удивлялся, почему это не работает :D Спасибо! - person rubix_addict; 09.04.2015
comment
Уааааааааааааааааааааааааааааааааааааааааааааааааааааааа... но исходный declval не объявляется как noexcept! Так почему же это работает для моего кода? - person rubix_addict; 09.04.2015
comment
@rubix_addict Объявлено noexcept: en.cppreference.com/w/cpp/utility/declval - person 0x499602D2; 09.04.2015
comment
О, ты прав. Извини. Я быстро просмотрел сигнатуру declval на cppreference и не понял, что дальше по тексту нет никакой спецификации. - person rubix_addict; 09.04.2015