![](/img/trans.png)
[英]static_assert in templated member function of non-template class
[英]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
我知道这不是一个学术上的答案,对标准更了解的人可以引用标准中的类型推导规则,但最终这些规则在某种程度上受上述解释的推动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.