容器值与智能ptr容器的模板重载

时间:2017-07-11 16:44:38

标签: c++ c++14

模板新手,所以我认为代码段最能说明我的问题。

#include <iostream>
#include <memory>
#include <string>
#include <algorithm>
#include <vector>
#include <type_traits>


template <typename TContainer, typename T>
bool contains(const TContainer& container, const T& t){
    auto begin = container.begin();
    auto end   = container.end();
    auto predicate = [&t](const auto& cT){
        return cT == t;
    };
    auto iter = std::find_if(begin, end, predicate);

    return iter != end;
}

struct Foo{
    int _value;
    Foo(int value) : _value{value} {}

    bool operator==(const Foo& other) const{
        return _value == other._value;
    }
};


int main(){
    using SmartFoo      = std::shared_ptr<Foo>;
    auto valueContainer = std::vector<Foo>{{1},{2},{3}};
    auto ptrContainer   = std::vector<SmartFoo>{{std::make_unique<Foo>(1)},
                                                {std::make_unique<Foo>(2)},
                                                {std::make_unique<Foo>(3)}};

    auto needle         = Foo(2);
    auto smartNeedle    = std::make_shared<Foo>(3);

    auto found          = contains(valueContainer, needle);
    auto smartFound     = contains(ptrContainer, smartNeedle);

    std::cout<<std::boolalpha;
    std::cout<<"Found by value?: " <<  found << "\n";
    std::cout<<"Found by smartptr?: " << smartFound << "\n";
    return 0;
}

基本上我有一些包含智能指针的容器,以及一些容纳值对象的容器,但在这两种情况下我只对值对象本身感兴趣。 上面的输出

Found by value?: true
Found by smartptr?: false

这显然是因为operator== shared_ptr检查地址而不是内容。

我正在努力实现一个谓词,如果T是一个智能ptr,那么将会对T进行去除,因此比较发生在值而不是地址上。理想情况下,我想将任一类型的容器传递给相同的contains。两种选择都可以吗?如果是这样,怎么样?

2 个答案:

答案 0 :(得分:4)

您可以使用过载:

$keyboard =      [['text' => $text]];
$replymarkup =   [   
    'keyboard' => $keyboard ,
    'resize_keyboard' => true ,
    'one_time_keyboard' => true 
];
$encodemarkup = json_encode($replymarkup);
$welcome = $text;
$url = "$website/sendmessage?chat_id=$chat_id&text=$welcome&    disable_notification=true&reply_markup=$encodemarkup";
file_get_contents($url); //It does not mute notification

然后

template <typename T>
bool cmp_value(const T& lhs, const T& rhs)
{
    return lhs == rhs;
}

template <typename T>
bool cmp_value(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs)
{
    return *lhs == *rhs;
}

答案 1 :(得分:2)

你可以像标准库那样做,并提供一个带比较器的重载。然后,如果你想使用默认的operator ==,你可以在不指定比较器的情况下调用函数,如果你需要一个特殊的(更复杂的)比较,你可以将它传递给函数。

template <typename TContainer, typename T>
bool contains(const TContainer& container, const T& t){
    auto begin = container.begin();
    auto end   = container.end();
    auto predicate = [&t](const auto& cT){
        return cT == t;
    };
    auto iter = std::find_if(begin, end, predicate);

    return iter != end;
}

template <typename TContainer, typename T, typename Compare>
bool contains(const TContainer& container, const T& t, Compare comp){
    auto begin = container.begin();
    auto end   = container.end();
    auto predicate = [&t, &comp](const auto& cT){
        return comp(cT, t);
    };
    auto iter = std::find_if(begin, end, predicate);

    return iter != end;
}