Search code examples
c++visual-studio-2017noexcept

Use of noexcept operator in template


I have tried to understand a bit more how does the noexcept operator works and how it can be used in template. My goal was to enable or disable a template function, depending on the noexcept type of one the member function class.

class ObjTestNoExcept
{
public:
   ObjTestNoExcept() noexcept {}
   void Test() noexcept {}
};

class ObjTestExcept
{
public:
   ObjTestExcept() {}
   void Test() {}
};

template <class T, typename = typename std::enable_if_t<noexcept(T().Test()), T>>
void DoSomething()
{
   std::cout << "OK" << std::endl;
}

int main()
{
   DoSomething<ObjTestNoExcept>();
   DoSomething<ObjTestExcept>(); // error C2672: 'DoSomething': no matching overloaded function found
   return 0;
}

It works as expected for the ObjTextExcept class and disables the function, and it works as expected for the ObjTestNoExcept class and enables the function.

However, if I remove the noexcept keyword on the ObjTestNoExcept class then the function is disabled whereas it's still noexcept.

class ObjTestNoExcept
{
public:
   ObjTestNoExcept() {}
   void Test() noexcept {}
};

template <class T, typename = typename std::enable_if_t<noexcept(T().Test()), T>>
void DoSomething()
{
   std::cout << "OK" << std::endl;
}

int main()
{
   DoSomething<ObjTestNoExcept>(); // error C2672: 'DoSomething': no matching overloaded function found
   return 0;
}

I can not figure out what is wrong with the removal of the noexcept keyword on the constructor.

This code has been developed under Visual Studio 2017 Professional Version 15.6.3.

Thanks for reading.

Olivier


Solution

  • noexcept(X) is true, if the expression X is noexcept. In the second example (noexcept(T().Test())), two things are mixed: the construction of T, then the call to the Test method. That's why the removal of the noexcept from the constructor breaks the code.

    To avoid assuming a noexcept default constructor, use: noexcept(std::declval<T>().Test())