C++ 判断一个容器是否有::find()
C++ determine if a container has ::find()
我有一个仿函数,它对类型为 T
的元素类型为 U
的容器进行操作,就像这样
template<typename T, template<typename...> class U>
class asserter
{
public:
asserter(U<T> &c) : container(c) { };
void operator()(T lhs)
{
CU_ASSERT(container.find(lhs) != container.end());
};
private:
U<T> &container;
};
我可能会将其用作
std::set<std::string> a, c;
...
asserter<std::string, std::set> ass(c);
for_each(a.begin(), a.end(), ass);
我们暂时忽略了 std::includes()
。
如果容器是定义了 U::find()
的容器,这会很好用。如果不是,我想回到 std::find()
。另一方面,如果可用,我宁愿使用 U::find()
而不是 std::find()
。
在 C++11(或必要时为 17)中,我能否确定 U::find()
是否对 U 可用(可能限制为 STL),如果可用,则使用它,否则使用 std::find()
?
SFINAE 关于表达式 c.find(value)
是否合式。 Trailing return 类型是 C++11,无论如何这里都不是必需的;它只是使 return 类型更容易编写 - decltype(c.find(value))
而不是 decltype(std::declval<Container&>().find(std::declval<const T&>()))
.
如果表达式格式错误,find_impl
的第一个重载将从重载集中删除,留下第二个重载作为唯一可行的重载。第三个参数的常用 int/long/0
技巧使第一个重载成为首选,当两个都可行时。
template<class Container, class T>
auto find_impl(Container& c, const T& value, int) -> decltype(c.find(value)){
return c.find(value);
}
template<class Container, class T>
auto find_impl(Container& c, const T& value, long) -> decltype(std::begin(c)){
return std::find(std::begin(c), std::end(c), value);
}
template<class Container, class T>
auto find(Container& c, const T& value) -> decltype(find_impl(c, value, 0)) {
return find_impl(c, value, 0);
}
通常的免责声明适用:这依赖于表达式 SFINAE,MSVC 目前不支持它; Microsoft 确实计划在 MSVC 2015 的更新中添加支持。
我有一个仿函数,它对类型为 T
的元素类型为 U
的容器进行操作,就像这样
template<typename T, template<typename...> class U>
class asserter
{
public:
asserter(U<T> &c) : container(c) { };
void operator()(T lhs)
{
CU_ASSERT(container.find(lhs) != container.end());
};
private:
U<T> &container;
};
我可能会将其用作
std::set<std::string> a, c;
...
asserter<std::string, std::set> ass(c);
for_each(a.begin(), a.end(), ass);
我们暂时忽略了 std::includes()
。
如果容器是定义了 U::find()
的容器,这会很好用。如果不是,我想回到 std::find()
。另一方面,如果可用,我宁愿使用 U::find()
而不是 std::find()
。
在 C++11(或必要时为 17)中,我能否确定 U::find()
是否对 U 可用(可能限制为 STL),如果可用,则使用它,否则使用 std::find()
?
SFINAE 关于表达式 c.find(value)
是否合式。 Trailing return 类型是 C++11,无论如何这里都不是必需的;它只是使 return 类型更容易编写 - decltype(c.find(value))
而不是 decltype(std::declval<Container&>().find(std::declval<const T&>()))
.
如果表达式格式错误,find_impl
的第一个重载将从重载集中删除,留下第二个重载作为唯一可行的重载。第三个参数的常用 int/long/0
技巧使第一个重载成为首选,当两个都可行时。
template<class Container, class T>
auto find_impl(Container& c, const T& value, int) -> decltype(c.find(value)){
return c.find(value);
}
template<class Container, class T>
auto find_impl(Container& c, const T& value, long) -> decltype(std::begin(c)){
return std::find(std::begin(c), std::end(c), value);
}
template<class Container, class T>
auto find(Container& c, const T& value) -> decltype(find_impl(c, value, 0)) {
return find_impl(c, value, 0);
}
通常的免责声明适用:这依赖于表达式 SFINAE,MSVC 目前不支持它; Microsoft 确实计划在 MSVC 2015 的更新中添加支持。