【发布时间】:2014-10-29 14:40:02
【问题描述】:
我正在创建一个非常小的 C++ 项目,我想根据自己的需要创建一个简单的矢量类。 std::vector 模板类不行。当向量类由chars(即vector<char>)组成时,我希望它能够与std::string 进行比较。经过一番折腾,我编写了既能编译又能做我想做的代码。见下文:
#include <string>
#include <stdlib.h>
#include <string.h>
template <typename ElementType>
class WorkingSimpleVector {
public:
const ElementType * elements_;
size_t count_;
// ...
template <typename ET = ElementType>
inline typename std::enable_if<std::is_same<ET, char>::value && std::is_same<ElementType, char>::value, bool>::type
operator==(const std::string & other) const {
if (count_ == other.length())
{
return memcmp(elements_, other.c_str(), other.length()) == 0;
}
return false;
}
};
template <typename ElementType>
class NotWorkingSimpleVector {
public:
const ElementType * elements_;
size_t count_;
// ...
inline typename std::enable_if<std::is_same<ElementType, char>::value, bool>::type
operator==(const std::string & other) const {
if (count_ == other.length())
{
return memcmp(elements_, other.c_str(), other.length()) == 0;
}
return false;
}
};
int main(int argc, char ** argv) {
// All of the following declarations are legal.
WorkingSimpleVector<char> wsv;
NotWorkingSimpleVector<char> nwsv;
WorkingSimpleVector<int> wsv2;
std::string s("abc");
// But this one fails: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’
NotWorkingSimpleVector<int> nwsv2;
(wsv == s); // LEGAL (wanted behaviour)
(nwsv == s); // LEGAL (wanted behaviour)
// (wsv2 == s); // ILLEGAL (wanted behaviour)
// (nwsv2 == s); // ??? (unwanted behaviour)
}
我相信我明白为什么会发生错误:编译器为NotWorkingSimpleVector<int> 创建了类定义,然后我的operator== 函数的返回类型变为:
std::enable_if<std::is_same<int, char>::value, bool>::type
然后变成:
std::enable_if<false, bool>::type
然后产生错误:std::enable_if<false, bool> 中没有type 成员,这确实是enable_if 模板的全部要点。
我有两个问题。
- 为什么 SFINAE 不会像我想要的那样简单地为
NotWorkingSimpleVector<int>禁用operator==的定义?这是否有一些兼容性原因?我还缺少其他用例吗?这种行为是否存在合理的反驳论点? - 为什么第一类 (
WorkingSimpleVector) 有效?在我看来,编译器“保留判断”:由于尚未定义“ET”参数,因此它放弃了判断operator==是否存在的尝试。我们是否依赖编译器“缺乏洞察力”来允许这种有条件启用的功能(即使 C++ 规范可以接受这种“缺乏洞察力”)?
【问题讨论】:
标签: c++ templates c++11 enable-if