静态非模板成员函数与静态模板成员函数

时间:2014-05-06 16:26:08

标签: c++ boost

#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>吗?

谢谢

1 个答案:

答案 0 :(得分: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 - &gt; boost::shared_ptr<const long>可以转换为boost::shared_ptr<int>T = Foo (其中Foo是用户定义的类) - &gt; boost::shared_ptr<const Foo>可以转换为boost::shared_ptr<int>。所以他没有办法推断T。我知道这不是学术上的答案,而且对标准更有见识的人可以从标准中引用类型推导规则,但最终这些规则在某种程度上受到上述解释的推动。