IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ typename使用時機 -> 正文阅读

[C++知识库]C++ typename使用時機

C++ typename使用時機

前言

PCL中的surface/include/pcl/surface/mls.h裡宣告的pcl::MovingLeastSquares類別有這麼一段代碼:

using KdTree = pcl::search::Search<PointInT>;
//typename specifies that it is the name of a type
using KdTreePtr = typename KdTree::Ptr;
// 模板中的參數已經給定,是個具體的類型,所以不用加typename告知編譯器它是一個類別
using NormalCloud = pcl::PointCloud<pcl::Normal>;
using NormalCloudPtr = NormalCloud::Ptr;

using PointCloudOut = pcl::PointCloud<PointOutT>;
using PointCloudOutPtr = typename PointCloudOut::Ptr;
using PointCloudOutConstPtr = typename PointCloudOut::ConstPtr;

using PointCloudIn = pcl::PointCloud<PointInT>;
using PointCloudInPtr = typename PointCloudIn::Ptr;
using PointCloudInConstPtr = typename PointCloudIn::ConstPtr;

using SearchMethod = std::function<int (pcl::index_t, double, pcl::Indices &, std::vector<float> &)>;

觀察KdTreeKdTreePtr,可以發現一個沒加,另一個則有加typename。他們之間的區別詳見下文。

KdTreePtr

KdTree::Ptr簡化前為pcl::search::Search<PointInT>::Ptr,因為它具體是什麼要依賴於PointInT,在編譯時並不知道它是一個類別,所以在這裡加上typename讓編譯器知道。

參考C++ Cast Template,如果我們要調用castpcl::search::Search<PointInT>::Ptr做型別轉換,編譯器在不知道pcl::search::Search<PointInT>::Ptr是一個類型的情況下,可能會把cast當成它的成員變量,因而導致編譯錯誤。所以這裡加上typename讓編譯器知道它是一個類別後,就能成功編譯了。

KdTree

那麼為什麼KdTree不用加typename呢?參考Where and why do I have to put the “template” and “typename” keywords?

There are many names for which typename is not necessary, because the compiler can, with the applicable name lookup in the template definition, figure out how to parse a construct itself - for example with T *f;, when T is a type template parameter. But for t::x * f; to be a declaration, it must be written as typename t::x *f;.

我們可以用模板參數T直接去定義一個變量,但是如果想要用T::x定義一個變量卻是行不通的(編譯器會把x當作T類型的成員變量),必須要在T::x之前加上typename,讓編譯器知道它是一個類型才行。

The syntax allows typename only before qualified names - it is therefore taken as granted that unqualified names are always known to refer to types if they do so.

typename關鍵字只能加在qualified names(可以想成有帶::的類別名稱)之前,unqualified names總是會被當成類別名稱,所以不需要加typename關鍵字。

來看一下qualified name的定義,參考Qualified name lookup

A qualified name is a name that appears on the right hand side of the scope resolution operator :: (see also qualified identifiers). A qualified name may refer to a

    class member (including static and non-static functions, types, templates, etc)
    namespace member (including another namespace)
    enumerator 

它將qualified name的定義說得很明白,也就是::運算符後面的名稱。qualified name可以是一個類別的成員,命名空間的成員,或是enum。

在這邊的例子中,將模板參數PointT代入pcl::search::Search<PointInT>後,編譯器便可以很容易地知道它是一個類型(對照上面的T* f),所以不需要加typename

如果我們想用pcl::search::Search<PointInT>::Ptr定義一個變數,因為它是一個qualified name(對照上面的T::x* f),所以必須在它之前加上typename

範例程序

以下程序展示typename的使用時機:

#include <iostream>
#include <memory>

template<typename T>
class Animal{
public:
    using Ptr = std::shared_ptr< Animal< T > >;
};

template<typename T>
void f(){
    Animal<T> a;

    //error: need ‘typename’ before ‘Animal<T>::Ptr’ because ‘Animal<T>’ is a dependent scope
    //error: expected ‘;’ before ‘ap’
    //Animal<T>::Ptr ap;

    typename Animal<T>::Ptr ap;
}

int main(){
    Animal<int> a;
    Animal<int>::Ptr ap;
    return 0;
}

首先定義一個模板類別Animal,裡面有個成員Ptr

main函數中,因為我們給定了Animal的模板參數,所以編譯器知道他們兩個都代表一種類型,可以成功編譯。

f函數中,我們可以用Animal<T>定義一個變數a,但是卻無法用Animal<T>::Ptr去定義變數ap,必須在之前加上typename才行。這是因為在T不確定的情況下,編譯器把Ptr當成Animal<T>類別的成員變數而不把它視為一個類型,因此無法用它去定義其他變數。

以上程序放在typename_keyword.cpp

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-29 08:54:26  更:2021-08-29 08:54:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:32:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码