sfinae 检测容器:std:array 失败
sfinae to detect containers: failure for std:array
我正在寻找一种使用 SFINAE 来实现某些功能的方法,该功能必须仅对某些容器可用:
vector, list, array (集合在下面仅作为测试)
建立在 this answer 的基础上,我尝试了下面的代码,它使用了一个特征 class,returns 仅对所需的容器为真。
如您所见 online here,std::array
.
失败
template <typename Container>
struct is_container : std::false_type { };
template <typename... Ts> struct is_container<std::array<Ts... >> : std::true_type { };
template <typename... Ts> struct is_container<std::vector<Ts...>> : std::true_type { };
template <typename... Ts> struct is_container<std::set<Ts... >> : std::true_type { };
template <typename... Ts> struct is_container<std::list<Ts... >> : std::true_type { };
template <typename... Ts> struct Dummy{};
int main()
{
std::cout << "Dummy: " << is_container<Dummy<int>>::value << '\n';
std::cout << "array: " << is_container<std::array<int,5>>::value << '\n';
std::cout << "vector:" << is_container<std::vector<int>>::value << '\n';
std::cout << "set: " << is_container<std::set<int>>::value << '\n';
std::cout << "list: " << is_container<std::list<int>>::value << '\n';
}
据我了解,这是因为 std::array
需要第二个模板参数。
我对可变参数模板的经验不足,所以我的问题是:
有没有办法让这个方法成功?
或者我应该使用链接问题中描述的另一种方法吗?
我宁愿有纯 C++11 的东西,但 C++14 也可以。
问题是std::array
的第二个模板参数是一个非类型模板参数,它不匹配类型模板参数包typename... Ts
。
您可以将 std::array
的专业化更改为:
template <typename T, std::size_t S> struct is_container<std::array<T, S>> : std::true_type { };
这不是 SFINAE,而是常规模板专业化。您的 std::array 未被识别,因为类型 std::size_t 的值(即 std::array 的第二个参数)is not 类型名称。
您可以具体更改对数组的检查:
template <typename T, std::size_t N> struct is_container<std::array<T,N>> : std::true_type { };
template <typename... Ts> struct is_container<std::vector<Ts...>> : std::true_type { };
如果您真的想使用 SFINAE 检查任何行为类似于容器的东西,您可以检查 std::begin、std::end、std::size 是否存在对于那种类型。
我正在寻找一种使用 SFINAE 来实现某些功能的方法,该功能必须仅对某些容器可用: vector, list, array (集合在下面仅作为测试)
建立在 this answer 的基础上,我尝试了下面的代码,它使用了一个特征 class,returns 仅对所需的容器为真。
如您所见 online here,std::array
.
template <typename Container>
struct is_container : std::false_type { };
template <typename... Ts> struct is_container<std::array<Ts... >> : std::true_type { };
template <typename... Ts> struct is_container<std::vector<Ts...>> : std::true_type { };
template <typename... Ts> struct is_container<std::set<Ts... >> : std::true_type { };
template <typename... Ts> struct is_container<std::list<Ts... >> : std::true_type { };
template <typename... Ts> struct Dummy{};
int main()
{
std::cout << "Dummy: " << is_container<Dummy<int>>::value << '\n';
std::cout << "array: " << is_container<std::array<int,5>>::value << '\n';
std::cout << "vector:" << is_container<std::vector<int>>::value << '\n';
std::cout << "set: " << is_container<std::set<int>>::value << '\n';
std::cout << "list: " << is_container<std::list<int>>::value << '\n';
}
据我了解,这是因为 std::array
需要第二个模板参数。
我对可变参数模板的经验不足,所以我的问题是:
有没有办法让这个方法成功? 或者我应该使用链接问题中描述的另一种方法吗?
我宁愿有纯 C++11 的东西,但 C++14 也可以。
问题是std::array
的第二个模板参数是一个非类型模板参数,它不匹配类型模板参数包typename... Ts
。
您可以将 std::array
的专业化更改为:
template <typename T, std::size_t S> struct is_container<std::array<T, S>> : std::true_type { };
这不是 SFINAE,而是常规模板专业化。您的 std::array 未被识别,因为类型 std::size_t 的值(即 std::array 的第二个参数)is not 类型名称。
您可以具体更改对数组的检查:
template <typename T, std::size_t N> struct is_container<std::array<T,N>> : std::true_type { };
template <typename... Ts> struct is_container<std::vector<Ts...>> : std::true_type { };
如果您真的想使用 SFINAE 检查任何行为类似于容器的东西,您可以检查 std::begin、std::end、std::size 是否存在对于那种类型。