繁体   English   中英

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

[英]static non-template member function vs. static template member function

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM