模板新手,所以我认为代码段最能说明我的问题。
#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
。两种选择都可以吗?如果是这样,怎么样?
答案 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;
}