c++ - SFINAE 的问题

标签 c++ templates sfinae

我试图重载运算符 - 以便它对其参数应用集合差异。因为我无法弄清楚如何将它限制为仅用于 STL 容器(因为如果我不这样做,它会覆盖每个运算符 - 看起来),我试图将它限制为仅设置和 vector ,因为我会与那些一起使用二。 这是我的代码:

#define RANGE(x) (x).begin(), (x).end()

template<class T>
struct is_STL_container
{
    static const bool value = false;
};

template<class T, typename alloc>
struct is_STL_container<std::vector<T, alloc>>
{
    static const bool value = true;
};

template<class T, class comp, typename alloc>
struct is_STL_container<std::set<T, comp, alloc>>
{
    static const bool value = true;
};


template <class T1, class T2,
class std::enable_if<is_STL_container<T1>::value && is_STL_container<T2>::value, T1>::type>
T1 operator - (const T1 &l, const T2 &r)
{
    assert(typeid(T1::value_type) == typeid(T2::value_type));

    std::vector<T1::value_type> result;
    std::set_difference(RANGE(l), RANGE(r), std::back_inserter(result));
    return T1(RANGE(result));
}

但是当我尝试编译我的程序时,出现以下错误:

Error   2   error C1903: unable to recover from previous error(s); stopping compilation C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\algorithm    3071    1   TrafficLight
Error   1   error C2893: Failed to specialize function template 'unknown-type std::less<void>::operator ()(_Ty1 &&,_Ty2 &&) const'  C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\algorithm    3071    1   TrafficLight

我想不出问题 我正在使用 VS2013

最好的问候 乌作

最佳答案

您的代码存在许多语法错误。以下示例有效。

注意: operator-以下是 T 的模板而不是 T1T2因为我不确定你是否真的想要允许 operator-在使用不同类型的 vector 时工作,例如std::vector<int>std::vector<double> .

示例代码

#include <algorithm>
#include <iostream>
#include <set>
#include <vector>

#define RANGE(x) (x).begin(), (x).end()

template<class T>
struct is_STL_container
{
    static const bool value = false;
};

template<class T, typename alloc>
struct is_STL_container<std::vector<T, alloc>>
{
    static const bool value = true;
};

template<class T, class comp, typename alloc>
struct is_STL_container<std::set<T, comp, alloc>>
{
    static const bool value = true;
};

template <class T>
typename std::enable_if<is_STL_container<T>::value && is_STL_container<T>::value, T>::type
operator-(const T &l, const T &r)
{
    T result;
    std::set_difference(RANGE(l), RANGE(r), std::back_inserter(result));
    return result;
}

int main()
{
    std::vector<int> a = { 1, 2, 3, 4, 5 };
    std::vector<int> b = { 2, 3, 4 };
    std::vector<int> r = a - b;
    for (const auto& v : r)
    {
        std::cout << v << " ";
    }

    return 0;
}

示例输出

1 5 

Live Example


编辑 1

注意:正如@StoryTeller 在评论中指出的那样,模板 operator-就在T会阻止 operator- 的有效使用在 std::vector<int> 之间和 std::set<int> (正如OP所尝试的那样)。以下代码使用 T1T2来解决这个问题。

示例代码

#include <algorithm>
#include <cassert>
#include <iostream>
#include <set>
#include <typeinfo>
#include <vector>

#define RANGE(x) (x).begin(), (x).end()

template<class T>
struct is_STL_container
{
    static const bool value = false;
};

template<class T, typename alloc>
struct is_STL_container<std::vector<T, alloc>>
{
    static const bool value = true;
};

template<class T, class comp, typename alloc>
struct is_STL_container<std::set<T, comp, alloc>>
{
    static const bool value = true;
};


template <class T1, class T2>
typename std::enable_if<is_STL_container<T1>::value && is_STL_container<T2>::value, T1>::type
operator-(const T1 &l, const T2 &r)
{
    assert(typeid(typename T1::value_type) == typeid(typename T2::value_type));

    T1 result;
    std::set_difference(RANGE(l), RANGE(r), std::back_inserter(result));
    return result;
}

int main()
{
    std::vector<int> a = { 1, 2, 3, 4, 5 };
    std::vector<int> b = { 2, 3, 4 };
    std::set<int> c = { 2, 3, 4 };

    std::vector<int> r = a - b;
    for (const auto& v : r)
    {
        std::cout << v << " ";
    }

    std::cout << "\n";

    r = a - c;
    for (const auto& v : r)
    {
        std::cout << v << " ";
    }

    return 0;
}

示例输出

1 5 
1 5 

Live Example

关于c++ - SFINAE 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35182975/

相关文章:

c++ - 拦截并将 C 调用转发给第三方库

python - 如何在 Django 模板中访问外键表的数据?

c++ - 检测 SFINAE 的 POD 类型的第一个成员

c++ - C2995 : template already defined

c++ - Win32 应用程序。 HBITMAP LoadImage 无法加载任何内容

c++ - 将带有前置和后置增量运算符的 C++ 转换为 Python 时出现问题

c++ - 使用 qFromBigEndian 从 Char 转换为 Int 表示 : "No matching function for call to"

c++ - 可变数量的构造函数参数取决于整数模板

c++ - 获取函数的第一个输入类型

c++ - 迭代器或指针的 std::enable_if 或 SFINAE