error C2784 ,class in key map - c++

I have a problem with the container map. I need to store my own class Person in key but i have error C2784 (i.e., "The compiler cannot determine a template argument from the supplied function arguments."). It's example from the book "Ivor Horton's beginning Visual C++ 2010"
#include<map>
#include<string>
#include <iostream>
using namespace std;
void main()
{
class Person{
public:
string c_name,c_surname;
Person(string name,string surname){
c_name=name;
c_surname=surname;
}
};
map<Person,string> phonebook;
phonebook.insert(make_pair(Person("Mel","GIBSON"),"24 32 23"));
phonebook[Person("Mel2","Gibson2")]="243 32 23";
/* it doesn`t work too
typedef pair<Person,string> Entry;
Entry entry1= Entry(Person("Jack","Jones"),"213 567 1234");
phonebook.insert(entry1);*/
system("Pause");
}
Error 1 error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const main::Person' e:\microsoft visual studio 10.0\vc\include\xfunctional 125 1 AllClasses
Error 2 error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'const main::Person' e:\microsoft visual studio 10.0\vc\include\xfunctional 125 1 AllClasses
Error 3 error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const main::Person' e:\microsoft visual studio 10.0\vc\include\xfunctional 125 1 AllClasses
Error 4 error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const main::Person' e:\microsoft visual studio 10.0\vc\include\xfunctional 125 1 AllClasses
Error 5 error C2784: 'bool std::operator <(const std::unique_ptr<_Ty,_Dx> &,const std::unique_ptr<_Ty2,_Dx2> &)' : could not deduce template argument for 'const std::unique_ptr<_Ty,_Dx> &' from 'const main::Person' e:\microsoft visual studio 10.0\vc\include\xfunctional 125 1 AllClasses
Error 6 error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const main::Person' e:\microsoft visual studio 10.0\vc\include\xfunctional 125 1 AllClasses
Error 7 error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const main::Person' e:\microsoft visual studio 10.0\vc\include\xfunctional 125 1 AllClasses
Error 8 error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const main::Person' e:\microsoft visual studio 10.0\vc\include\xfunctional 125 1 AllClasses
Error 9 error C2676: binary '<' : 'const main::Person' does not define this operator or a conversion to a type acceptable to the predefined operator e:\microsoft visual studio 10.0\vc\include\xfunctional 125 1 AllClasses

The problem here is that std::map requires your keys to be comparable with the < operator. Custom structures/classes are not that by default, you need to make a custom operator< for comparison.

In C++03 you could not use local classes (classes defined within functions) as template arguments.
In C++11 you can.
So one fix is to update the compiler (there is Visual C++ 2013), and another fix is to move the class definition out of main.
By the way, void main is invalid as standard C++, and as standard C, and it's more to type than standard int main. If your book has void main, then that's a very ungood book. Microsoft's examples that include void main are also very ungood.
Also, by the way, the
system("Pause");
at the end is also very ungood practice because
it is not necessary, has no advantage, but
it makes the program more difficult to use and has some other problems, and to top it all,
it's Windows-specific, non-portable code.
To run a console program so that it stops at the end
in Visual Studio use Ctrl+F5, or
in Visual Studio place a breakpoint at the end of main (just click in the left margin) and run it with debugging (e.g. via keypress F5), or
run it from a command interpreter.
UPDATE: the now added error messages (even the first one) mention operator<. You need to define that also. That is, define an operator< function for your class Person.

Related

Error with xstdde "could not deduce template argument..."

I'm working on a asteroids game replica. This error I'm getting is beyond my understanding so I hope you can help.
In my code I have a class name asteroid that stores every asteroid object. Within this class I have a public function that's called create() which has the parameter sf::ConvexShape (if you don't know what sf::ConvexShape is, it is a function in the SFML library). I also have a std::map<asteroid, sf::ConvexShape> to store asteroid objects as the key and their shapes as the .second
The error is a runtime error, everything is fine in the compiler. The error reports are gibberish to me, but there was a part that mentioned "iterator" and "std::vector" which makes me think I'm doing something wrong passing iterators to the create() function?
Here is the error log:
Error 5 error C2784: 'bool std::operator <(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::vector<_Ty,_Alloc> &' from 'const asteroid' C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xstddef 180 1 SFML testing
Error 10 error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const asteroid' C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xstddef 180 1 SFML testing
Error 12 error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const asteroid' C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xstddef 180 1 SFML testing
Error 9 error C2784: 'bool std::operator <(const std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::move_iterator<_RanIt> &' from 'const asteroid' C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xstddef 180 1 SFML testing
Error 8 error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const asteroid' C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xstddef 180 1 SFML testing
Error 6 error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const asteroid' C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xstddef 180 1 SFML testing
Error 4 error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const asteroid' C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xstddef 180 1 SFML testing
Error 11 error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const asteroid' C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xstddef 180 1 SFML testing
Error 7 error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'const asteroid' C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xstddef 180 1 SFML testing
Error 13 error C2676: binary '<' : 'const asteroid' does not define this operator or a conversion to a type acceptable to the predefined operator C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xstddef 180 1 SFML testing
Also full sauce here.
Why am I getting these errors? How can I fix it?
Let me know if there is something I forgot to mention, its hard to know what to ask when I don't understand the problem.
std::map stores things in a sorted order. If you don't tell it how to sort, it will use operator <. Your problem is that given:
asteroid a, b;
a < b; // Not defined.
You need something like:
bool operator <( const asteroid& lhs, const asteroid& rhs)
{
????
}
Except that you can't use the position (because that keeps changing). Perhaps you should do:
class asteroid
{
static unsigned global_id;
unsigned id;
.... // Previous contents as before.
}
asteroid::asteroid() : id (global_id++) { ... }
and then
bool operator <( const asteroid& lhs, const asteroid& rhs)
{
lhs.id < rhs.id;
}

Errors 2676 and 2784 (...could not deduce template argument for...) when inserting vector of structs into set

I am getting the following build errors when I try to run my program (in VS):
Error 10 error C2676: binary '<' : 'const move' does not define this operator or a conversion to a type acceptable to the predefined operator
Error 4 error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'const move'
Error 8 error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const move'
Error 1 error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const move'
Error 3 error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const move'
Error 5 error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const move'
Error 6 error C2784: 'bool std::operator <(const std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::move_iterator<_RanIt> &' from 'const move'
Error 9 error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const move'
Error 7 error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const move'
Error 2 error C2784: 'bool std::operator <(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::vector<_Ty,_Alloc> &' from 'const move'
I have no idea why they are occurring, as I haven't defined any operators in my move struct (see below), nor are there any operators in the part of my code that causes it.
They seem to be caused by this function (which is never called):
std::set<solution> solve(grid board, solution prev) {
std::set<solution> ret = {};
ret.insert(prev);
return ret;
}
My typedefs/structs that are used above:
struct move {
public:
move(unsigned startX, unsigned startY, unsigned endX, unsigned endY) {
x0 = startX;
y0 = startY;
x1 = endX;
y1 = endY;
}
unsigned x0 : 4, y0 : 4, x1 : 4, y1 : 4;
};
typedef std::vector<std::vector<__int8>> grid;
typedef std::pair<__int8, __int8> point;
typedef std::vector<move> solution;
Can anyone tell me why this is happening, and what I can do to fix it?
Thanks in advance!
There are two more things in Steephen's answer that just don't fit. The first is mostly formal, std::set uses std::less by default, not operator<. This only matters in cornercases though, because std::less uses operator< by default. There is a different issue though, and that merits a different answer, because I can't format code properly in a comment.
When passing a custom comparator to std::set as second template parameter, you must make sure that it defines a strict-weak ordering. That means that the comparator cmp must satisfy certain requirements. In particular cmp(a, a) = false and cmp(a, b) -> not cmp(b, a), which is used by the set (but also e.g. std::map) to determine equality. If cmp(a, b) = false and cmp(b, a) = false ("neither is less than the other"), it will treat the two values as equal.
Concerning the vector that you have, one suggestion was to use the euclidean distance. The euclidean distance between (3, 0) and (0, 4) is 5, as is that between (0, 3) and (4, 0), (0, 0) and (-5, 0) and infinitely many others. That means that different vectors would be considered equal, which is probably not what you wanted.
As a rule of thumb, a lexicographical sorting is a good default. In order to implement that, you simply split the operands into tuples so that each tuple value can be compared numerically. The implementation then looks like this:
bool compare_move(move const& m1, move const& m2)
{
if (m1.x0 != m2.x0) return m1.x0 < m2.x0;
if (m1.y0 != m2.y0) return m1.y0 < m2.y0;
if (m1.x1 != m2.x1) return m1.x1 < m2.x1;
return m1.y1 < m2.y1;
}
This also has the advantage that it doesn't use floating-point math. It could be improved a bit using the fact that you have bitfields with just 4 bit, so every move only occupies 16 bit of data. If you combine those to a single integer value by shifting and OR'ing them, you would get the same, but I'm not sure if that microoptimization is even worth it.
std::set creates a binary tree internally using comparison operator < by default, that is the reason you got the error specified in your question. So std::set has to keep an order internally for all its elements. So each time we insert, it will check new elements order among existing elements using comparison operator and position it accordingly.
You have to define operator < as follows inside struct move before doing insertion to std::set. I hope you can compare using http://en.wikipedia.org/wiki/Euclidean_distance
bool move::operator <(struct move & rhs)
{
return ( sqrt( (this->x1-this->x0)* (this->x1-this->x0) +
(this->y1-this->y0) * (this->y1-this->y0) ) <
sqrt( (rhs.x1-rhs.x0)* (rhs.x1-rhs.x0) +
(rhs.y1-rhs.y0) * (rhs.y1-rhs.y0) ) );
}
If you prefer to keep a custom comparison in place of <, you can do it as follows. Define your comparison operator 'customcompare` and define std::set as follows:
std::set<std::vector<move>,customcompare> ret;

Priority queue works with vectors but not lists

I am tightening up some rendering code and instead of storing all my renderable objects in a plain ol vector I decided to use a priority queue (this way things like transparency can be automatically prioritized correctly). I cannot get it to work with a list as the underlying data structure however. I have tried it using both a functor and by overloading the < operator. It complains about:
Error 8 error C2676: binary '-' : 'std::_List_iterator<std::_List_val<std::_List_simple_types<IRenderable *>>>' does not define this operator or a conversion to a type acceptable to the predefined operator c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 2425 1 ObjLoaded
Error 4 error C2676: binary '-' : 'std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<IRenderable *>>>' does not define this operator or a conversion to a type acceptable to the predefined operator c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 2331 1 ObjLoaded
Error 7 error C2784: 'unknown-type std::operator -(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'std::_List_iterator<std::_List_val<std::_List_simple_types<IRenderable *>>>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 2425 1 ObjLoaded
Error 3 error C2784: 'unknown-type std::operator -(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<IRenderable *>>>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 2331 1 ObjLoaded
Error 6 error C2784: 'unknown-type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'std::_List_iterator<std::_List_val<std::_List_simple_types<IRenderable *>>>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 2425 1 ObjLoaded
Error 2 error C2784: 'unknown-type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<IRenderable *>>>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 2331 1 ObjLoaded
Error 5 error C2784: 'unknown-type std::operator -(std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'std::move_iterator<_RanIt> &' from 'std::_List_iterator<std::_List_val<std::_List_simple_types<IRenderable *>>>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 2425 1 ObjLoaded
Error 1 error C2784: 'unknown-type std::operator -(std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'std::move_iterator<_RanIt> &' from 'std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<IRenderable *>>>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 2331 1 ObjLoaded
This is how I am declaring the priority queue:
priority_queue<IRenderable*, list<IRenderable*>> m_renderlist;
with the overloaded < operator. If I make one simple change, everything runs:
priority_queue<IRenderable*, vector<IRenderable*>> m_renderlist;
Any Idea why might be happening here? For completeness, here is my overload and functor:
bool IRenderable::operator<(const IRenderable* comp)
{
if (this->GetPriority() < comp->GetPriority())
return true;
return false;
}
//class IRenderableComp
//{
//public:
// bool operator()(const IRenderable* first, const IRenderable* second)
// {
// if (first->GetPriority() < second->GetPriority())
// return true;
// return false;
// }
//};
Not super important because I can get it working with vectors, but this little stuff bugs me and I want to understand why. Any insight would be appreciated. Thanks
23.6.4/1 Any sequence container with random access iterator and supporting operations front(), push_back() and pop_back() can be used to instantiate priority_queue.
23.3.5.1/1 list is a sequence container that supports bidirectional iterators...
Emphasis mine.

std::map with an object as value

I have an error while trying to use std::map with my own class as value. The definition of the map is this:
std::map<std::string,CCrossSection> Xsects;
This line compiles fine (so it kindo of works?)
Xsects[sectionId].m_vProfile.push_back(pt);
When I try to iterate over the map however:
for (std::map<std::string,CCrossSection>::iterator xs = Xsects.begin(); xs < Xsects.end(); xs++) {
it->second.SaveFile(f);
}
It gives me multiple errors similar to this:
error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'std::_Tree<_Traits>::iterator'
with
[
_Traits=std::_Tmap_traits<std::string,CCrossSection,std::less<std::string>,std::allocator<std::pair<const std::string,CCrossSection>>,false>
]
c:\program files\microsoft visual studio 9.0\vc\include\xtree(1466) : see declaration of 'std::operator <'
I thought that it is a problem with less operator and I added it to my definition of the class CCrossSection, but it didn't change a thing. Later I read that the key of the map has to have less operator defined and I think std::string has. Any ideas why it happens?
Cheers
Tomek
it will compile when you compare the end iterator with operator!=

Creating boost::thread with an std::shared_ptr object instance

I have the following two code segments. The first block compiles and works as expected. However the second block does not compile.
My question is, given the code below what is the correct syntax when trying to create a thread based on an instance of an object that is being proxied by a shared_ptr?
#include <iostream>
#include <new>
#include <memory>
#include <boost/thread.hpp>
struct foo
{
void boo() {}
};
int main()
{
//This works
{
foo* fptr = new foo;
boost::thread t(&foo::boo,fptr);
t.join();
delete fptr;
}
//This doesn't work
{
std::shared_ptr<foo> fptr(new foo);
boost::thread t(&foo::boo,fptr);
t.join();
}
return 0;
}
The compiler error:
Error 5 error C2784: 'T *boost::get_pointer(T *)' : could not deduce template argument for 'T *' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest
Error 3 error C2784: 'T *boost::get_pointer(const std::auto_ptr<_Ty> &)' : could not deduce template argument for 'const std::auto_ptr<_Ty> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest
Error 4 error C2784: 'T *boost::get_pointer(const std::auto_ptr<_Ty> &)' : could not deduce template argument for 'const std::auto_ptr<_Ty> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest
Error 8 error C2784: 'T *boost::get_pointer(const boost::shared_ptr<X> &)' : could not deduce template argument for 'const boost::shared_ptr<X> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest
Error 9 error C2784: 'T *boost::get_pointer(const boost::shared_ptr<X> &)' : could not deduce template argument for 'const boost::shared_ptr<X> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest
Error 1 error C2784: 'T *boost::get_pointer(const boost::scoped_ptr<T> &)' : could not deduce template argument for 'const boost::scoped_ptr<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest
Error 2 error C2784: 'T *boost::get_pointer(const boost::scoped_ptr<T> &)' : could not deduce template argument for 'const boost::scoped_ptr<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest
Error 6 error C2784: 'T *boost::get_pointer(const boost::reference_wrapper<T> &)' : could not deduce template argument for 'const boost::reference_wrapper<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest
Error 7 error C2784: 'T *boost::get_pointer(const boost::reference_wrapper<T> &)' : could not deduce template argument for 'const boost::reference_wrapper<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest
Error 10 error C2784: 'T *boost::get_pointer(const boost::intrusive_ptr<T> &)' : could not deduce template argument for 'const boost::intrusive_ptr<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest
Error 11 error C2784: 'T *boost::get_pointer(const boost::intrusive_ptr<T> &)' : could not deduce template argument for 'const boost::intrusive_ptr<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest
The problem is that boost::thread relies on boost::mem_fn to handle member functions, and boost::mem_fn (or at least the version you are using) doesn't know how to use a std::shared_ptr to invoke a member function as it expects you to use boost::shared_ptr or one of the myriad of other smart pointer types in your error listing.
The raw pointer works because boost::mem_fn already has that overload. The solutions are to use boost::shared_ptr or std::mem_fn. The latter works because std::mem_fn knows how to interact with std::shared_ptr
boost::thread t(std::mem_fn(&foo::boo), fptr);
An alternative to Dave S's answer is to define this (before <boost/mem_fn.hpp> gets included):
namespace boost
{
template<typename T>
inline T*
get_pointer(const std::shared_ptr<T>& p)
{ return p.get(); }
}
That "teaches" boost::mem_fn to obtain a raw pointer from a std::shared_ptr.
In C++11 std::mem_fn is required to work with any pointer-like type, simply by dereferencing it i.e. *fptr, but boost::mem_fn instead uses *boost::get_pointer(fptr). I don't know if it's fixed in the latest version of Boost, but I would argue that it should use SFINAE to detect whether get_pointer will work, and should just dereference it otherwise.