如果传入任何类型的列表,则尝试禁用函数
Trying to disable a function if any type of list is passed in
如果将任何类型的列表 class 传递给具有以下 enable_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)
但是当我用 vector<int>
调用 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
向量确实有成员 typedef value_type
来获取存储在其中的东西的值..
知道如何解决这个问题吗?
我的回答基于 this 所以 post。更好的方法如下:
#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)
这样做的主要优势在于,使用 std::list
类型参数的其余部分将无法绕过您的检查。
直接问题在这里:
std::list<typename ContainerType::value_type>>::value>>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
在您的示例中,ContainerType
是一个引用类型 (std::vector<int>&
),您不能从引用类型访问 typedef。您必须先删除引用。
但我们可以通过忽略 KeyType
部分来简化它:
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&& ) { ... }
如果将任何类型的列表 class 传递给具有以下 enable_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)
但是当我用 vector<int>
调用 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
向量确实有成员 typedef value_type
来获取存储在其中的东西的值..
知道如何解决这个问题吗?
我的回答基于 this 所以 post。更好的方法如下:
#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)
这样做的主要优势在于,使用 std::list
类型参数的其余部分将无法绕过您的检查。
直接问题在这里:
std::list<typename ContainerType::value_type>>::value>>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
在您的示例中,ContainerType
是一个引用类型 (std::vector<int>&
),您不能从引用类型访问 typedef。您必须先删除引用。
但我们可以通过忽略 KeyType
部分来简化它:
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&& ) { ... }