是否可以检查是否为给定的类型和参数定义了用户字面量? [英] Is it possible to check if a user literal is defined for given type and argument?

查看:101
本文介绍了是否可以检查是否为给定的类型和参数定义了用户字面量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在编译时检查用户文字 _name 是否为类型 Ret 和参数 Arg 。虽然我有半解决方案,它需要至少定义一次运算符:

I want to check at compile-time if user literal _name is defined for type Ret and argument Arg. While I have half-solution, it requires the literal operator to be defined at least once:

#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 有成员成员,但我不知道在这种情况下是否可行)

But if there isn't at least one definition of possibly overloaded user literal, this solution will not work. Is there any way to check it even for non-existing literals (possibly the same way we can check if class X has member member, but I don't know if it's viable in this case)?

推荐答案


是否可以检查是否为给定的类型和参数定义了用户文字?

Is it possible to check if an user literal is defined for given type and argument?

例如,您可以在示例代码中使用以下特化:

As an example, you can use the following specialization in your example code:

template<class T, class S> 
struct has_literal_x <T, S,
      std::enable_if_t<std::is_same<decltype(operator""_x(std::declval<S>())), T>::value>
    > : std::true_type
{ };

这很快就会变成:

#include <iostream>
#include <type_traits>
#include <utility>

struct one { };
struct two { };

//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::enable_if_t<std::is_same<decltype(operator""_x(std::declval<S>())), T>::value> 
    > : 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;
}

输出是预期的输出: 0

The output is the expected one: 0 for all of them.

另一种方法是在C ++ 14 @ Jarod42的此答案是通过模板变量。

作为示例:

Another way to do that in C++14 (mostly inspired by this answer of @Jarod42) is by means of a template variable.
As an example:

template<typename T, typename S, typename = void>
constexpr bool has_literal_v = false;

template<typename T, typename S>
constexpr bool has_literal_v<T, S, std::enable_if_t<std::is_same<decltype(operator""_x(std::declval<S>())), T>::value>> = true;

main p>

The main would become instead:

int main()
{  
    std::cout << has_literal_v<one, char const*> << std::endl;
    std::cout << has_literal_v<two, unsigned long long int> << std::endl;

    std::cout << has_literal_v<one, unsigned long long int> << std::endl;
    std::cout << has_literal_v<two, char const*> << std::endl;

    std::cout << has_literal_v<int, char const*> << std::endl;
}



我发现很容易阅读,这是一个 constexpr 变量。还有什么?

这篇关于是否可以检查是否为给定的类型和参数定义了用户字面量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆