您可以使用 別名宣告 來宣告名稱,以做為先前宣告類型的同義字。 (這種機制也稱為 類型別名)。 您也可以使用此機制來建立 別名範本,這對於自訂配置器很有用。
語法
using identifier = type;
備註
識別碼
別名的名稱。
type
您要為其建立別名的類型識別碼。
別名不會引進新的類型,而且無法變更現有類型名稱的意義。
別名的最簡單形式相當於 typedef 來自 C++03 的機制:
// C++11
using counter = long;
// C++03 equivalent:
// typedef long counter;
這兩種形式都可讓您建立 類型的 counter變數。 更有用的是像 std::ios_base::fmtflags 的這個類類型名:
// C++11
using fmtfl = std::ios_base::fmtflags;
// C++03 equivalent:
// typedef std::ios_base::fmtflags fmtfl;
fmtfl fl_orig = std::cout.flags();
fmtfl fl_hex = (fl_orig & ~std::cout.basefield) | std::cout.showbase | std::cout.hex;
// ...
std::cout.flags(fl_hex);
別名也適用於函式指標,但比對等的 typedef 更容易閱讀:
// C++11
using func = void(*)(int);
// C++03 equivalent:
// typedef void (*func)(int);
// func can be assigned to a function pointer value
void actual_function(int arg) { /* some code */ }
func fptr = &actual_function;
機制的限制 typedef 是它不適用於範本。 不過,C++11 的類類型名語法啟用別名樣板的建立:
template<typename T> using ptr = T*;
// the name 'ptr<T>' is now an alias for pointer to T
ptr<int> ptr_int;
範例
下列範例示範如何搭配使用別名樣板與自訂配置器 (在這個案例中為整數向量類型)。 您可以替代任何類型 int ,以建立方便的別名,以隱藏主要功能程式代碼中的複雜參數清單。 透過在整個程式代碼中使用自定義配置器,您可以改善可讀性,並降低引入錯字所造成的錯誤的風險。
#include <stdlib.h>
#include <new>
template <typename T> struct MyAlloc {
typedef T value_type;
MyAlloc() { }
template <typename U> MyAlloc(const MyAlloc<U>&) { }
bool operator==(const MyAlloc&) const { return true; }
bool operator!=(const MyAlloc&) const { return false; }
T * allocate(const size_t n) const {
if (n == 0) {
return nullptr;
}
if (n > static_cast<size_t>(-1) / sizeof(T)) {
throw std::bad_array_new_length();
}
void * const pv = malloc(n * sizeof(T));
if (!pv) {
throw std::bad_alloc();
}
return static_cast<T *>(pv);
}
void deallocate(T * const p, size_t) const {
free(p);
}
};
#include <vector>
using MyIntVector = std::vector<int, MyAlloc<int>>;
#include <iostream>
int main ()
{
MyIntVector foov = { 1701, 1764, 1664 };
for (auto a: foov) std::cout << a << " ";
std::cout << "\n";
return 0;
}
1701 1764 1664
Typedefs
typedef宣告引進名稱,其範圍內會成為宣告類型宣告部分所指定類型的同義字。
您可以使用 typedef 宣告,針對語言或已宣告的類型,建構更簡短或更有意義的名稱。 Typedef 名稱可讓您封裝可能變更的實作詳細資料。
與 、 classstruct和 union 宣告相反enum,typedef宣告不會引進新的類型; 它們會為現有類型引進新的名稱。
使用 typedef 宣告的名稱會佔用與其他標識符相同的命名空間(語句標籤除外)。 因此,除了類別類型宣告之外,它們不能使用與先前宣告之名稱相同的標識碼。 請考慮下列範例:
// typedef_names1.cpp
// C2377 expected
typedef unsigned long UL; // Declare a typedef name, UL.
int UL; // C2377: redefined.
與其他標識碼相關的名稱隱藏規則也會控管使用 typedef宣告的名稱可見度。 因此,下列範例在 C++ 中是合法的:
// typedef_names2.cpp
typedef unsigned long UL; // Declare a typedef name, UL
int main()
{
unsigned int UL; // Redeclaration hides typedef name
}
// typedef UL back in scope
另一個名稱實例隱藏:
// typedef_specifier1.cpp
typedef char FlagType;
int main()
{
}
void myproc( int )
{
int FlagType;
}
當您以與 typedef相同的名稱宣告區域範圍標識符時,或當您在相同範圍或內部範圍中宣告結構或等位的成員時,必須指定類型規範。 例如:
typedef char FlagType;
const FlagType x;
若要重複使用 FlagType 名稱做為識別項、結構成員或等位成員的名稱,必須提供類型:
const int FlagType; // Type specifier required
只有下列做法是不夠的:
const FlagType; // Incomplete specification
FlagType因為會被視為型別的一部分,而不是要重新宣告的標識符。 此宣告會採用為不合法的宣告,類似於:
int; // Illegal declaration
您可以使用 typedef 宣告任何類型,包括指標、函式和陣列類型。 您可以在定義結構或等位類型之前宣告結構或等位類型指標的 typedef 名稱,只要定義的可見度和宣告相同即可。
範例
宣告的 typedef 其中一個用法是讓宣告更加統一且精簡。 例如:
typedef char CHAR; // Character type.
typedef CHAR * PSTR; // Pointer to a string (char *).
PSTR strchr( PSTR source, CHAR target );
typedef unsigned long ulong;
ulong ul; // Equivalent to "unsigned long ul;"
若要在 typedef 相同的宣告中指定基本和衍生型別,您可以使用逗號分隔宣告子。 例如:
typedef char CHAR, *PSTR;
下列範例提供類型 DRAWF 給未傳回任何值的函式,並且接受兩個 int 引數:
typedef void DRAWF( int, int );
在上述 typedef 語句之後,宣告
DRAWF box;
相當於下列宣告:
void box( int, int );
typedef 通常會結合 struct 來宣告和命名使用者定義型別:
// typedef_specifier2.cpp
#include <stdio.h>
typedef struct mystructtag
{
int i;
double f;
} mystruct;
int main()
{
mystruct ms;
ms.i = 10;
ms.f = 0.99;
printf_s("%d %f\n", ms.i, ms.f);
}
10 0.990000
重新宣告 typedefs
宣告 typedef 可用來重新宣告相同名稱,以參考相同的類型。 例如:
來源檔案 file1.h:
// file1.h
typedef char CHAR;
來源檔案 file2.h:
// file2.h
typedef char CHAR;
來源檔案 prog.cpp:
// prog.cpp
#include "file1.h"
#include "file2.h" // OK
檔案 prog.cpp 包含兩個頭檔,兩者都包含 typedef 名稱 CHAR的宣告。 只要兩個宣告都參考相同的類型,就可以接受此類重新宣告。
typedef無法重新定義先前宣告為不同類型的名稱。 請考慮此替代方法 file2.h:
// file2.h
typedef int CHAR; // Error
編譯程式會在 中 prog.cpp 發出錯誤,因為嘗試重新宣告名稱 CHAR 以參考不同的類型。 此原則延伸至建構,例如:
typedef char CHAR;
typedef CHAR CHAR; // OK: redeclared as same type
typedef union REGS // OK: name REGS redeclared
{ // by typedef name with the
struct wordregs x; // same meaning.
struct byteregs h;
} REGS;
C++與 C 中的 typedefs
typedef由於 ANSI C 在宣告中typedef宣告未命名結構的做法,因此支援搭配類別類型使用規範。 例如,許多 C 程式設計人員會使用下列成語:
// typedef_with_class_types1.cpp
// compile with: /c
typedef struct { // Declare an unnamed structure and give it the
// typedef name POINT.
unsigned x;
unsigned y;
} POINT;
這類宣告的優點是可以執行類似以下的宣告:
POINT ptOrigin;
而非:
struct point_t ptOrigin;
在C++中,typedef名稱與實數類型之間的差異(以 class、 structunion、 和 enum 關鍵詞宣告)比較明顯。 雖然在語句中 typedef 宣告無名稱結構的 C 做法仍然有效,但它在 C 中不會提供表示法優點。
// typedef_with_class_types2.cpp
// compile with: /c /W1
typedef struct {
int POINT();
unsigned x;
unsigned y;
} POINT;
上述範例會使用未命名的類別語法宣告名為 POINT 的類別 typedef 。
POINT 是類別名稱;不過,以此方式產生的名稱會受到下列限制:
名稱 (同義字) 不能出現在、
class或struct前置詞之後union。名稱不能當做類別宣告內的建構函式或解構函式名稱使用。
總而言之,此語法不會提供繼承、建構或解構的任何機制。