引用容器的C ++模板专业化

时间:2018-07-17 11:55:35

标签: c++ templates c++14 sfinae template-specialization

#include "stdafx.h"

#include <algorithm>

class MyClass {
};

template <typename C, typename V, typename Enable = void>
static bool Contains(const C& container, const V& value) {
    auto iter = std::find(container.begin(), container.end(), value);
    auto result = (iter != container.end());
    return result;
}

template <typename C, typename V,
          typename std::enable_if<std::is_same<std::reference_wrapper<const V>, typename C::value_type>::value, bool>::type>
static bool Contains(const C& container, const V& value) {
    auto iter = std::find_if(container.begin(), container.end(), [&](auto& aValue) {
        return (aValue.get() == value);
    });
    auto result = (iter != container.end());
    return result;
}

int main() {
    const MyClass a;
    auto container = {
        std::reference_wrapper<const MyClass>(a),
    };
    Contains(container, a);
    return 0;
}

编译器:VC ++ 2015U3

编译错误:

  

严重性代码描述项目文件行抑制状态   错误C2678二进制'==':找不到左手运算符   'const std :: reference_wrapper'类型的操作数(或   没有可接受的转换)ConsoleApplication1 c:\ program   文件(x86)\ Microsoft Visual Studio 14.0 \ vc \ include \ xutility 3258

它运行在第一个实现中,而不是第二个实现中。

对此有任何想法吗?

2 个答案:

答案 0 :(得分:1)

您需要定义operator ==来比较类实例:

bool operator ==(MyClass const & left, MyClass const & right) { return false; }

此运算符将由std::findstd::find_if算法调用(在第二种情况下位于lambda return (aValue.get() == value);内部)。

答案 1 :(得分:1)

也许您还需要operator==()的{​​{1}},但是,为了解决专业化问题,我认为最好使用显式专业化

MyClass

代替SFINAE。

例如,如果您也使SFINAE可以启用reference-wrapper-container版本

template <template <typename...> class C, typename V>
static bool Contains (C<std::reference_wrapper<V const>> const & container,
                      V const & value) {
    auto iter = std::find_if(container.begin(), container.end(), [&](auto& aValue) {
        return (aValue.get() == value);
    });
    auto result = (iter != container.end());
    return result;
}

template <typename C, typename V> static std::enable_if_t<std::is_same<std::reference_wrapper<const V>, typename C::value_type>::value, bool> Contains (const C& container, const V& value) 函数的两个版本都与调用匹配

Contains()

没有人是首选。