[英]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.