2014-05-06 53 views
1
#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; 
} 

问题>为什么TestClass::CreateT(shpInt)不起作用,而TestClass::Create(shpInt)正常工作。是否因为TestClass::CreateT是仅支持静态绑定的模板函数,无法自动从boost::shared_ptr<T>转换为boost::shared_ptr<const T>静态非模板成员函数与静态模板成员函数

谢谢

+0

对于'CreateT',它应该尝试转换哪一个(许多'T'可能是可能的)?顺便说一句,'CreateT (shpInt)'应该有效。 – Jarod42

+0

是的,它在我做出更改后生效。为什么最初的那个不起作用? – q0987

+0

我的意思是:如何boost :: shared_ptr '和'boost :: shared_ptr '有关系吗? (你期望'T == U') – Jarod42

回答

2

非模板版本的工作,因为没有涉及类型推演。编译器知道和类型的类型为他必须转换(如果它们不是相同的类型),并简单地检查是否有可能的转换。

对于模板版本,这不再是真实的。他首先必须推导出模板。

boost::shared_ptr<const int>boost::shared_ptr<const T>,因为一个完美的匹配,发现这个很简单:Tint(所以需要也不参与任何转换)。

对于从boost::shared_ptr<int>boost::shared_ptr<const T>的匹配,没有产生相同两种类型的T。所以问题是'什么是T?' 对你来说它可能是显而易见的(你仍然是错的),但编译器不能推导出T,因为它不是一个完美的匹配。次好的是两种类型之间的转换,但这意味着要尝试T(它们是无限的)的所有可能性,并查看哪一种产生可转换类型。例如。 T = long - >boost::shared_ptr<const long>可以是转换为boost::shared_ptr<int>T = Foo(其中Foo是一个用户定义的类) - >boost::shared_ptr<const Foo>可以是转换为boost::shared_ptr<int>。所以他无法推断出T。我知道这不是一个学术答案,而对标准更为了解的人可以从标准中引用类型推导规则,但最终这些规则有些受到上述解释的启发。