Я хочу проверить во время компиляции, если пользовательский литерал _name
определен для типа Ret
и аргумента Arg
. Хотя у меня есть половинное решение, для этого требуется, чтобы литерал operator
определялся хотя бы один раз:
#include <iostream>
#include <type_traits>
struct one { };
struct two { };
// we need at least one of these definitions for template below to compile
one operator"" _x(char const*) {return {};}
two operator"" _x(unsigned long long int) {return {};}
template<class T, class S, class = void>
struct has_literal_x : std::false_type
{ };
template<class T, class S>
struct has_literal_x <T, S,
std::void_t<decltype((T(*)(S))(operator"" _x))>
> : std::true_type
{ };
int main()
{
std::cout << has_literal_x<one, char const*>::value << std::endl;
std::cout << has_literal_x<two, unsigned long long int>::value << std::endl;
std::cout << has_literal_x<one, unsigned long long int>::value << std::endl;
std::cout << has_literal_x<two, char const*>::value << std::endl;
std::cout << has_literal_x<int, char const*>::value << std::endl;
}
Вывод:
1
1
0
0
0
Но если нет хотя бы одного определения, возможно, перегруженного пользовательского литерала, это решение не будет работать. Есть ли способ проверить это даже на несуществующие литералы (возможно, так же, как мы можем проверить, имеет ли класс X
член member
, но я не знаю, насколько он жизнеспособен в этом случае)?