静态非模板成员函数与静态模板成员函数
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>
,这很简单,因为找到了一个完美匹配:T
是int
(因此不需要也不涉及转换)。
对于从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
。我知道这不是一个学术上的答案,更了解标准的人可以从标准中引用类型演绎规则,但最终这些规则在一定程度上受到上述解释的推动。
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 将公共但非静态的成员函数与ALGLIB集成
- 使用指向成员的指针将成员函数作为参数传递
- 将重载的成员函数传递给函数模板
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 如何在C++中使用非静态成员函数作为回调函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 关联容器的下界复杂性:成员函数与非成员函数
- 在 C++ 中用派生类型重写成员函数
- 链表的泛型函数remove()与成员函数remove)
- 如何将lambda作为模板类的成员函数参数
- constexpr构造函数需要常量成员函数时出现问题
- 将自由函数绑定为类成员函数
- 区分非成员函数和头文件中的成员函数
- 如何从子成员函数修改父公共成员变量
- 保留对其他类的成员函数的引用
- 在运算符重载定义中使用成员函数(const错误)
- 内联如何影响模块接口中的成员函数
- 将成员函数指针作为参数传递给模板方法