如何解决SFINAE:“ enable_if”不能用于禁用此声明
我想在模板类中启用和禁用函数声明,仅基于模板参数是否定义了我使用boost/tti/has_type.hpp
的一种类型。但是,我收到了编译器的抱怨,即'enable_if'不能用于禁用此声明。
#include <boost/tti/has_type.hpp>
#include <iostream>
#include <vector>
#include <set>
using namespace std;
BOOST_TTI_HAS_TYPE(key_type)
template <typename container>
class adapter : public container
{
public:
using container::container;
public:
template <typename type = typename enable_if<!has_type_key_type<container>::value,typename container::value_type>::type>
bool contains(typename container::value_type const & v) { return find(begin(*this),end(*this),v) != end(*this); }
template <typename type = typename enable_if<has_type_key_type<container>::value,typename container::value_type>::type>
bool contains(typename container::key_type const & k) { return this->find(k) != this->end(); }
};
int main()
{
cout << has_type_key_type<adapter<vector<int>>>::value << endl;
cout << has_type_key_type<adapter<set<int>>>::value << endl;
}
我该如何解决?但是,如果我将其更改为类似的非成员函数模板,则可以使用。
#include <boost/tti/has_type.hpp>
#include <iostream>
#include <vector>
#include <set>
using namespace std;
BOOST_TTI_HAS_TYPE(key_type)
template <typename container,typename enable_if<!has_type_key_type<container>::value,int>::type = 0>
bool contains(container const & c,typename container::value_type const & v) { return find(begin(c),end(c),v) != end(c); }
template <typename container,typename enable_if<has_type_key_type<container>::value,typename container::key_type const & k) { return c.find(k) != c.end(); }
template <typename container>
class adapter : public container
{
public:
using container::container;
public:
// ...
};
int main()
{
vector<double> v{3.14};
set<double> s{2.71};
cout << contains(v,3.14) << endl;
cout << contains(s,2.71) << endl;
}
解决方法
如果我将其更改为类似的非成员函数模板,则可以使用。
重点是:功能模板。
您的代码无效,因为SFINAE在模板上工作,并且测试与模板参数有关。您的contains()
方法是模板类内部的函数,但不是 template 函数。
要使SFINAE适用于contains()
,必须在模板函数中对其进行转换。
您已经看到它在课堂外有效,但在课堂内也有效。
例如,使用以下技巧(警告:未测试代码)
// .......VVVVVVVVVVVVVVVVVVVVVV
template <typename C = container,// ................V
typename std::enable_if<!has_type_key_type<C>::value,int>::type = 0>
bool contains (typename container::value_type const & v)
{ return find(begin(*this),end(*this),v) != end(*this); }
// .......VVVVVVVVVVVVVVVVVVVVVV
template <typename C = container,// ...............V
typename std::enable_if<has_type_key_type<C>::value,int>::type = 0>
bool contains (typename container::key_type const & k)
{ return this->find(k) != this->end(); }
观察到SFINAE测试(has_type_key_type<C>::value
)现在包含函数的模板参数C
,而不是类的模板参数container
。
如果您想避免constains()
被“劫持”(为C
设置类型,与container
不同,则可以添加可变参数非类型(未使用)模板参数。
例如
// .......VVVVVV
template <int...,typename C = container,typename std::enable_if<!has_type_key_type<C>::value,v) != end(*this); }
// .......VVVVVV
template <int...,typename std::enable_if<has_type_key_type<C>::value,int>::type = 0>
bool contains (typename container::key_type const & k)
{ return this->find(k) != this->end(); }
主题外:您至少可以使用C ++ 14,而您可以使用std::enable_if_t
,所以
std::enable_if_t<has_type_key_type<C>::value,int> = 0
代替
typename std::enable_if<has_type_key_type<C>::value,int>::type = 0
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。