【发布时间】:2015-08-05 21:45:54
【问题描述】:
我需要检查容器擦除函数是否返回迭代器。我通常会通过例如检查函数签名促进。但是在 boost 类(例如 flat_set)的情况下,擦除是继承的,因此检查不会发现。但我真的需要它。 SFINAE to check for inherited member functions 只展示了一个我还不能使用的 C++11 解决方案。
我尝试过这样的事情:
template <typename T>
class has_member_func_erase_it_constit
{
typedef typename T::iterator iterator;
typedef typename T::const_iterator const_iterator;
typedef BOOST_TYPEOF_TPL(&T::erase) eraseType;
typedef typename boost::function_types::result_type<eraseType>::type result;
public:
static const bool value = boost::is_same<iterator, result>::value;
};
template<class T>
struct EraseReturnsIterator
{
static CONSTEXPR bool value = has_member_func_erase_it_constit<T>::value;
};
但由于擦除过载而失败。我可能需要 decltype 或类似的东西来检查编译时使用 const_iterator 调用擦除的返回类型,但我找不到。
在 C++11 之前这怎么可能?
如果有一个擦除函数返回 void,这也不起作用:
template <typename T>
class has_member_func_erase_it
{
typedef typename T::iterator iterator;
typedef typename T::const_iterator const_iterator;
typedef char yes[1];
typedef char no [2];
static T makeT();
static iterator makeIt();
typedef BOOST_TYPEOF_TPL(makeT().erase(makeIt())) result;
public:
static const bool value = boost::is_same<iterator, result>::value;
};
【问题讨论】:
-
我怀疑你会更具体;一些容器有 > 1 个名为
erase的方法。例如,vector同时具有erase(iterator)和erase(iterator, iterator) -
在升级到 C++11 之前你会遇到多少个容器? 10?硬编码它们。 Ifdef C++11 做正确的事情,也许断言他们同意。
-
我的意思是检查“无效擦除(迭代器)”与“迭代器擦除(迭代器)”。但我找到了一个可行的解决方案,并将在今天晚些时候发布。这是一个非常好的邪恶模板诡计。
标签: c++ boost traits template-meta-programming c++03