C++ 尝试在传入任何类型的列表时禁用函数

C++ 尝试在传入任何类型的列表时禁用函数,c++,template-meta-programming,sfinae,C++,Template Meta Programming,Sfinae,我试图禁用一个函数,如果任何类型的列表类被传递到函数中,则使用以下enable\u if template <typename ContainerType, typename KeyType, typename = std::enable_if_t<!std::is_same< std::decay_t<ContainerType>, std::list<typename ContainerT

我试图禁用一个函数,如果任何类型的列表类被传递到函数中,则使用以下enable\u if

template <typename ContainerType, typename KeyType,
          typename = std::enable_if_t<!std::is_same<
            std::decay_t<ContainerType>,
            std::list<typename ContainerType::value_type>>::value>>
void func(ContainerType&& container, KeyType&& key)
模板>::值>>
void func(容器类型和容器、键类型和键)
但是当我用向量调用func时,我得到了一个错误

candidate template ignored: substitution failure [with ContainerType = std::__1::vector<int, std::__1::allocator<int> > &, KeyType = int]: type 'std::__1::vector<int, std::__1::allocator<int> > &' cannot be used prior to '::' because it has no
  members
忽略候选模板:替换失败[with ContainerType=std::_1::vector&,KeyType=int]:类型“std::_1::vector&”不能在“:”之前使用,因为它没有
成员
向量确实具有成员typedef
value\u type
,以获取存储在其中的对象的值

你知道我该怎么解决这个问题吗?

我的答案是基于这篇文章的。更好的方法如下:

#include <type_traits>

template<template<typename...> class TT, typename T>
struct is_instantiation_of : std::false_type { };

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of<TT, TT<Ts...>> : std::true_type { };

template <typename ContainerType, typename KeyType,
          typename = std::enable_if_t<!is_instantiation_of<
            std::list, std::decay_t<ContainerType>>::value>>
void func(ContainerType&& container, KeyType&& key)
#包括
模板
struct是:std::false_类型{}的_实例化_;
模板
struct是:std::true_类型{}的_实例化_;
模板::值>>
void func(容器类型和容器、键类型和键)

这样做的主要优点是,与其余的
std::list
s类型参数混在一起将不允许绕过您的检查。

直接的问题在于:

std::list<typename ContainerType::value_type>>::value>>
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

std::enable_if
可能应该是
std::enable_if_t
?@StoryTeller好眼力!但这并没有纠正错误:(我会接受这个答案,但上面的答案也说明了我为什么会犯错误,所以我会选择这个答案,尽管我把它投了更高的票。谢谢!
template <class X> struct is_list : std::false_type { };
template <class T, class A> struct is_list<std::list<T,A>> : std::true_type { };

template <class Container, class Key,
    std::enable_if_t<!is_list<std::decay_t<Container>>::value>* = nullptr>
void func(ContainerType&&, Key&& ) { ... }