1

I try to check template class T in function do_math() on the possibility of throwing an exception in the copy assignment operator.

But the following code throws an error:

template<class T>
void do_math()
    noexcept(noexcept(T(std::declval<T>())) && noexcept(std::declval<T>() + std::declval<T>()) && noexcept(std::declval<T>().operator = (std::declval<T>())) )
{

}
main.cpp:9:135: error: request for member ‘operator=’ in ‘std::declval<int>()’, which is of non-class type ‘int’
     noexcept(noexcept(T(std::declval<T>())) && noexcept(std::declval<T>() + std::declval<T>()) && noexcept(std::declval<T>().operator = (std::declval<T>())) )
                                                                                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~^

Please help me to write the correct check.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770

1 Answers1

4

You don't need to write this yourself. There is already a type trait for it in the standard library:

#include<type_traits>

and then

std::is_nothrow_copy_assignable<T>::value

gives you true/false and can be used in the noexcept specifier.

Similarly there is

std::is_nothrow_copy_constructible<T>::value

to check whether non-throwing copy construction is possible.

Note however that if T is not a lvalue reference type, then std::declval<T> is a rvalue, not a lvalue. Therefore your current code is testing for move constructibility, not copy constructibility. (There are analogous type traits for these as well.)

user17732522
  • 53,019
  • 2
  • 56
  • 105