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

static non-template member function vs. static template member function

本文关键字:成员 函数 静态      更新时间:2023-10-16
#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>的自动转换?

谢谢

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

对于模板化版本,这不再是正确的。他首先得推导出模板。

对于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。我知道这不是一个学术上的答案,更了解标准的人可以从标准中引用类型演绎规则,但最终这些规则在一定程度上受到上述解释的推动。