使用SFINAE和void_t区分类型 [英] Distinguish between types using SFINAE and void_t

查看:85
本文介绍了使用SFINAE和void_t区分类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了必须编写两个函数的情况,其中一个应使用原始类型和 std :: string 来调用。另一个应与其他类型一起调用。

I faced some situation where I have to write two functions, one of them should be invoked with primitive types and std::string. The other one should be called with other types.

到目前为止,我以可行的解决方案告终:

So far I ended with working solution:

template <typename...>
struct Void_t_helper {
    using type = void;
};

template <typename... Ts>
using Void_t = typename Void_t_helper<Ts...>::type;


template <typename T, typename = void>
struct Is_string : std::false_type {};

template <typename T> 
struct Is_string<T, Void_t<decltype (std::declval<T> ().c_str ())>> : std::is_same<decltype (std::declval<T> ().c_str ()), const char*>::type {};


template <typename T>
std::enable_if_t<Is_string<T>::value || std::is_arithmetic<T>::value, void> foo (T) {
    std::cout << "string or primitive\n";
}

template <typename T>
std::enable_if_t<!Is_string<T>::value && !std::is_arithmetic<T>::value, void> foo (T) {
    std::cout << "other type\n";
}

用法:

foo (1);
foo (1.2);
foo (std::string {"fsdf"});
foo (std::vector<int> {1, 2, 3});
foo (std::vector<std::string> {"a", "v", "c"});

按预期方式产生:

string or primitive
string or primitive
string or primitive
other type
other type

我的问题是:您知道更好的解决方案吗?

我不太确定是否可以找到 c_str()是否存在。我知道我可能可以为原始类型编写一些包装类,而 std :: string 会有一些 category_t 使用值 X 定义,对于其他类型,值 Y 定义并使用此类别区分这些组,但我仍然认为 c_str()检查更方便。

I am not really sure if checking if c_str() exists is the better option I can get. I am aware that I could probably write some wrapper class that for primitive types and std::string would have some category_t defined with value X, and for other types value Y and distinguish between these groups using this category, but still I think that c_str() checking is more convenient.

推荐答案


我不确定我是否可以更好地选择c_str()是否存在。

I am not really sure if checking if c_str() exists is the better option I can get.

理想情况下,将检查您的实际需求。

Ideally you'll be checking for what you actually want.

可以是一组已知类型或模板,也可以是一个概念

That can either be a set of known types or templates, or it can be a concept.

目前,您正在检查具有c_str()成员函数的概念,该函数返回指向常量chars的指针。

At the moment, you're checking for "the concept of having a c_str() member function which returns a pointer to constant chars".

问题是,您的SFINAE函数需要什么概念?

The question is, what concept does your SFINAE'd function need?

如果将使用 c_str()成员,那是合理的。但是,如果要使用其他成员或字符串类型,则可能要构建一个复合概念来描述要使用的接口部分。

If it will use the c_str() member, that's reasonable. But if it's going to use other members or types of the string, you probably want to build a compound concept to describe the parts of the interface you're going to exercise.

当然,您可能只想确认它实际上是 std :: string 的专业化名称。除非您陈述用例,否则很难(不可能)说出来。

Of course, you may just want to confirm that it is actually a specialisation of std::string. It's difficult (impossible) to tell unless you state the use case.

这篇关于使用SFINAE和void_t区分类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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