[英]Distinguish between types using SFINAE and void_t
I faced some situation where I have to write two functions, one of them should be invoked with primitive types and std::string
. 我遇到了必须编写两个函数的情况,其中一个函数应使用原始类型和
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";
}
And the usage: 以及用法:
foo (1);
foo (1.2);
foo (std::string {"fsdf"});
foo (std::vector<int> {1, 2, 3});
foo (std::vector<std::string> {"a", "v", "c"});
produces as expected: 产生预期的结果:
string or primitive
string or primitive
string or primitive
other type
other type
My question is: Do you know better solution to this kind of problem? 我的问题是: 您知道更好的解决方案吗?
I am not really sure if checking if c_str()
exists is the better option I can get. 我不太确定是否可以检查
c_str()
存在。 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. 我知道我可能会写一些包装器类,对于原始类型和
std::string
将使用一些值X
定义一些category_t
,对于其他类型的值Y
将使用该类别区分这些组,但是我仍然认为c_str()
检查更方便。
I am not really sure if checking if c_str() exists is the better option I can get.
我不太确定是否可以检查c_str()是否存在。
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 . 那可以是一组已知的类型或模板,也可以是一个概念 。
At the moment, you're checking for "the concept of having a c_str() member function which returns a pointer to constant chars". 目前,您正在检查“具有c_str()成员函数的概念,该函数返回指向常量chars的指针”。
The question is, what concept does your SFINAE'd function need? 问题是,您的SFINAE功能需要什么概念?
If it will use the c_str()
member, that's reasonable. 如果它将使用
c_str()
成员,那是合理的。 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. 但是,如果要使用字符串的其他成员或类型,则可能要构建一个复合概念来描述将要使用的接口的各个部分。
Of course, you may just want to confirm that it is actually a specialisation of std::string
. 当然,您可能只想确认它实际上是
std::string
。 It's difficult (impossible) to tell unless you state the use case. 除非您说明用例,否则很难(不可能)说出来。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.