Akıllı işaretçiyi std::map
için anahtar olarak test etmek için aşağıdaki koda sahibim, Mac ve Linux'ta kodu çalıştırıyorum, ancak farklı çıktılar gözlemledim, bir hata mı, yoksa yanlış bir şey mi yaptım? std::map
anahtarları karşılaştırmak için std::less<T>
kullanır: Mac'teHarita tuşu olarak akıllı işaretçiler
#include <iostream>
#include <memory>
#include <string>
#include <map>
using namespace std;
class Dog {
public:
typedef shared_ptr<Dog> sptr;
Dog(const string &name) : name_(name) { }
friend bool operator<(const Dog &lhs, const Dog &rhs) {
cout << "Dog::operator< called" << endl;
return lhs.name_ < rhs.name_;
}
friend bool operator<(const sptr &lhs, const sptr &rhs) {
cout << "Dog::operator< sptr called" << endl;
return lhs->name_ < rhs->name_;
}
private:
string name_;
};
void test_raw_object_as_map_key() {
cout << "raw object as map key ============== " << endl;
map<Dog, int> m;
m[Dog("A")] = 1;
m[Dog("B")] = 2;
m[Dog("C")] = 3;
m[Dog("A")] = 4;
cout << "map size: " << m.size() << endl;
}
void test_smart_pointer_as_map_key() {
cout << "smart pointer as map key ============== " << endl;
map<Dog::sptr, int> m;
m[make_shared<Dog>("A")] = 1;
m[make_shared<Dog>("B")] = 2;
m[make_shared<Dog>("C")] = 3;
m[make_shared<Dog>("A")] = 4;
cout << "map size: " << m.size() << endl;
}
int main(int argc, const char *argv[]) {
test_raw_object_as_map_key();
test_smart_pointer_as_map_key();
return 0;
}
:
Linux'ta[email protected]$ g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
[email protected]$ ./a.out
raw object as map key ==============
Dog::operator< called
Dog::operator< called
Dog::operator< called
Dog::operator< called
Dog::operator< called
Dog::operator< called
Dog::operator< called
Dog::operator< called
Dog::operator< called
map size: 3
smart pointer as map key ==============
Dog::operator< sptr called
Dog::operator< sptr called
Dog::operator< sptr called
Dog::operator< sptr called
Dog::operator< sptr called
Dog::operator< sptr called
Dog::operator< sptr called
Dog::operator< sptr called
Dog::operator< sptr called
map size: 3
: (Eğer g++
aslında clang olduğu gördüğünüz gibi Mac'te)
[email protected]$ g++ --version
g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[email protected]$ ./a.out
raw object as map key ==============
Dog::operator< called
Dog::operator< called
Dog::operator< called
Dog::operator< called
Dog::operator< called
Dog::operator< called
Dog::operator< called
Dog::operator< called
Dog::operator< called
Dog::operator< called
map size: 3
smart pointer as map key ==============
map size: 4
btw
map size: 3
kendiniz tanımlamak ve sonramap
onu kullanabilirsiniz bir arkadaş olmak zorunda değil, sadece dönebilir * lhs <* rhs; – o11c
@ o11c, evet, ama değişiklik hiçbir fark yaratmaz. – neevek
Muhtemelen ilgili: http://stackoverflow.com/questions/11115265/clang-stdshared-ptr-and-stdless-operator –