Использование оператора noexcept в шаблоне - PullRequest
0 голосов
/ 16 октября 2019

Я попытался немного больше понять, как работает оператор noexcept и как его можно использовать в шаблоне. Моей целью было включить или отключить функцию шаблона, в зависимости от типа noexcept одного класса функции-члена.

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;
}

Он работает, как и ожидалось, для класса ObjTextExcept, отключает функцию, работает, как и ожидалось, для класса ObjTestNoExcept и включает функцию.

Однако, если я удалю ключевое слово noexceptв классе ObjTestNoExcept функция отключена, тогда как она все еще не исключена.

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;
}

Я не могу понять, что не так с удалением ключевого слова noexcept в конструкторе.

Этот кодРазработано в Visual Studio 2017 Professional версии 15.6.3.

Спасибо за чтение.

Оливье

1 Ответ

2 голосов
/ 16 октября 2019

noexcept(X) - истина, если выражение X не является исключением. Во втором примере (noexcept(T().Test())) смешиваются две вещи: создание T, а затем вызов метода Test. Вот почему удаление noexcept из конструктора нарушает код.

Чтобы избежать использования конструктора noexcept по умолчанию, используйте: noexcept(std::declval<T>().Test())

...