.template cast<>中template的作用

.template cast<>中template的作用

PCL中的surface/include/pcl/surface/impl/mls.hpp裡有這麼一段代碼:

query_point = cloud[index].getVector3fMap ().template cast<double> ();

第一次看到.template cast<>這種寫法一定覺得不明所以,本篇的目的就是要探討template關鍵字在此處的作用。

首先得來了解一下C++編譯器是怎麼處理程式中的"name"(型別名稱,變數名稱,模板名稱等)的。

Where and why do I have to put the “template” and “typename” keywords?中引用了C++ Standard paragraph (3/7)

Some names denote types or templates. In general, whenever a name is encountered it is necessary to determine whether that name denotes one of these entities before continuing to parse the program that contains it. The process that determines this is called name lookup.

編譯器在解析C++程式的過程中會需要先區分出哪些name是型別名稱或模板名稱,而哪些不是,才能繼續往下進行,這個過程叫做name lookup

How will the compiler find out what a name t::x refers to, if t refers to a template type parameter? x could be a static int data member that could be multiplied or could equally well be a nested class or typedef that could yield to a declaration. If a name has this property - that it can't be looked up until the actual template arguments are known - then it's called a dependent name (it "depends" on the template parameters).

假設程式中有個t::x,其中的t是模板型別參數,編譯器看到了會把x當什麼呢?x可能是一個static成員變數,也可能是巢狀類別,或是一個typedef,它具體是什麼得先等t被解析出來才能知道,在這種情況下x被稱為dependent name(它依賴於模板參數t)。

Let's wait until the user instantiates the template, and then later find out the real meaning of t::x * f;.

雖然我們可以等到該模板被實例化之後再去解析x是什麼。

other implementations choose to check templates early on and give errors in the definition as soon as possible, before an instantiation even takes place.

但也有些編譯器的實作方式是選擇在實例化之前就去檢查模板。

So there has to be a way to tell the compiler that certain names are types and that certain names aren't.

在這種情況下,我們得自行告知編譯器程式中的哪些name是型別名稱而哪些不是。

在我們的例子中用到了template修飾字,參考The template keyword as qualifier (C++ only)

Use the keyword template as a qualifier to distinguish member templates from other entities.

template修飾字可以用來區分出哪些是member templates,而哪些不是。

其中member templates指的是:

Template declarations (class, function, and variables(since C++14)) can appear inside a member specification of any class, struct, or union that aren't local classes.

用白話來說就是出現在class/struct/union裡(所以才叫"member")的template class/function/variable。

Vector3fMap的類型是Eigen::Map<Eigen::Vector3f>,是一個模板類,因此cloud[index].getVector3fMap ()的具體類型在編譯時是不知道的(?),如果不加template關鍵字,因為name lookup是在模板實例化前進行的,所以編譯器並不知道cast是什麼。cast可能會被當作Eigen::Map<Eigen::Vector3f>類別的成員變數,cast後面跟着的<double><也就會被編譯器當作小於符號,導致編譯錯誤。

所以對於member templates,要在前面加上template關鍵字。在我們的例子中,template關鍵字告訴編譯器後面跟着的cast是一個templated method(它是template function,並且屬於Eigen::Map<Eigen::Vector3f>這個class),這樣才能通過編譯。

注:
common/include/pcl/impl/point_types.hpp中關於getVector3fMap函數的定義:

inline pcl::Vector3fMap getVector3fMap () { return (pcl::Vector3fMap (data)); } \

可以看到它回傳的類型為pcl::Vector3fMap,它的定義位於同一份檔案中:

using Vector3fMap = Eigen::Map<Eigen::Vector3f>;

關於Eigen::Map的作用,參看Eigen库中的Map类到底是做什么的? - Carpathia的回答 - 知乎

Map类用于通过C++中普通的连续指针或者数组 (raw C/C++ arrays)来构造Eigen里的Matrix类,这就好比Eigen里的Matrix类的数据和raw C++array 共享了一片地址,也就是引用。
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值