我正在与SFINAE进行斗争,试图拥有许多只需要使用运算符[]访问类型T的功能。到目前为止,我有以下代码可以在Visual Studio 2017中编译并正常工作:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <array>
#include <map>
#include <set>
using namespace std;
template <typename T, typename X = std::enable_if_t <std::is_array<T>::value || std::is_pointer<T>::value> >
void DoIt(T& c)
{}
template <typename T, typename std::enable_if_t< std::is_same<std::random_access_iterator_tag,
typename std::iterator_traits<typename T::iterator>::iterator_category>::value, bool> = true >
void DoIt(T& c)
{}
int main()
{
int* a;
const int* ac;
int b[10];
array<int,6> c;
vector<int> d;
string s;
DoIt(a); // Ok, compile pass
DoIt(ac); // Ok, compile pass
DoIt(b); // Ok, compile pass
DoIt(c); // Ok, compile pass
DoIt(d); // Ok, compile pass
DoIt(s); // Ok, compile pass
int i;
float f;
map<int, int> m;
//DoIt(f); // Ok, compile fails
//DoIt(i); // Ok, compile fails
// DoIt(m); // Ok, compile fails
return 0;
}
现在我需要以下内容:1.如何将针对数组和指针的SFINAE条件检查以及随机访问运算符合并为一项检查?我有很多函数,使用两个声明并不方便,代码太多。但是我以某种方式未能将条件合并到单个std :: enable_if_t或模板结构中。2.是否可以扩展上面的内容,并检查容器的类型,例如:
vector<int> a;
vector<string> b;
int* c;
string* d;
DoIt(a); // must pass
DoIt(c); // must pass
DoIt(b); // must fail
DoIt(d); // must fail
如何将针对数组和指针的SFINAE条件检查以及随机访问运算符合并为一项检查?我
我想到的最简单的方法是检查是否可以写c[0u]
template <typename T>
auto DoIt(T& c) -> decltype( c[0u], void() )
{}