Как лучше всего уведомить о неправильном создании экземпляров шаблона? - PullRequest
1 голос
/ 07 августа 2020

Как я могу сделать запрещенные экземпляры шаблонов четко видимыми во время компиляции? Я думал о том, чтобы выбросить исключение, унаследовав его:

template<string message> struct exception {};


template<class T> struct non_void;

template<class T> using non_void_t = typename non_void<T>::type;

template<> struct non_void<void>: exception<string{"non_void: argument is void"}> {};

non_void_t<void> poorly_typed_object;

, но g cc 10 просто жалуется на некоторую ошибку :

$ g++ -std=c++20 exc.cpp 
exc.cpp: In substitution of ‘template<class T> using non_void_t = typename non_void::type [with T = void]’:
exc.cpp:11:16:   required from here
exc.cpp:7:25: error: no type named ‘type’ in ‘struct non_void<void>’
    7 | template<class T> using non_void_t = typename non_void<T>::type;

и не отображать что-либо о родительском типе экземпляра erroneus, поэтому фактическое сообщение об ошибке никогда не появляется в выводе компилятора.

Есть ли способ сделать это более очевидным?

1 Ответ

2 голосов
/ 07 августа 2020

Я бы посоветовал сделать неудачную специализацию non_void_t<void> ограниченной частичной специализацией, которая запускает static_assert при создании экземпляра:

#include <type_traits>
template<class T> concept Void = std::is_void_v<T>;
template<Void T> struct non_void<T> { static_assert(!std::is_void_v<T>, "argument is void"); };

Пример .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...