#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
using namespace std;
struct TestClass
{
static void Create(boost::shared_ptr<const int> shp)
{
cout << "TestClass::Create: " << *shp << endl;
}
template <typename T>
static void CreateT(boost::shared_ptr<const T> shp)
{
cout << "TestClass::CreateT: " << *shp << endl;
}
};
int main()
{
boost::shared_ptr<int> shpInt = boost::make_shared<int>(10);
boost::shared_ptr<const int> shpConstInt = shpInt;
TestClass::Create( shpInt ); // OK
TestClass::Create( shpConstInt ); // OK
//error C2664: 'void TestClass::CreateT<int>(boost::shared_ptr<T>)' :
//cannot convert parameter 1 from 'boost::shared_ptr<T>' to 'boost::shared_ptr<T>'
TestClass::CreateT( shpInt ); // ERROR
TestClass::CreateT( shpConstInt ); // OK
// workaround
boost::shared_ptr<const int> shpConstInt2 = shpInt;
TestClass::CreateT( shpConstInt2 ); // OK
return 0;
}
问题&GT; TestClass::CreateT( shpInt )
工作正常时,为什么TestClass::Create( shpInt )
不起作用。是因为TestClass::CreateT
是一个仅支持静态绑定的模板函数,它无法自动从boost::shared_ptr<T>
转换为boost::shared_ptr<const T>
吗?
谢谢
答案 0 :(得分:2)
非模板化版本有效,因为不涉及类型推导。编译器知道类型从和类型到他必须转换(如果它们不是相同的类型),只需检查是否有转换。
对于模板化版本,这不再适用。他首先必须推断出模板。
对于boost::shared_ptr<const int>
到boost::shared_ptr<const T>
,这很简单,因为找到了完美匹配:T
是int
(因此不需要转换也不需要转换)。
对于从boost::shared_ptr<int>
到boost::shared_ptr<const T>
的匹配,没有T
可以产生相同的两种类型。所以问题是'什么是T
?'
对你来说这可能是显而易见的(你仍然会犯错),但编译器无法推断T
,因为它不是完美的匹配。接下来最好的事情是两种类型之间的转换,但这意味着尝试T
(无限)的所有可能性,并查看哪一种产生可转换类型。例如。 T
= long
- &gt; boost::shared_ptr<const long>
可以转换为boost::shared_ptr<int>
或T
= Foo
(其中Foo
是用户定义的类) - &gt; boost::shared_ptr<const Foo>
可以转换为boost::shared_ptr<int>
。所以他没有办法推断T
。我知道这不是学术上的答案,而且对标准更有见识的人可以从标准中引用类型推导规则,但最终这些规则在某种程度上受到上述解释的推动。