什麼是有效的函式模板過載

函式模板可以在非模板函式過載規則下過載(相同名稱,但引數型別不同),除此之外,如果過載,則過載是有效的

  • 返回型別不同,或
  • 模板引數列表不同,除了引數的命名和預設引數的存在(它們不是簽名的一部分)

對於普通函式,比較兩種引數型別對於編譯器來說很容易,因為它具有所有資訊。但是模板中的型別可能尚未確定。因此,兩個引數型別相等的規則在這裡是近似的,並且表示非依賴性型別和值需要匹配,並且依賴型別和表示式的拼寫需要相同(更準確地說,它們需要符合所謂的 ODR 規則,除了可以重新命名模板引數。但是,如果在這種不同的拼寫下,型別中的兩個值被認為是不同的,但總是例項化為相同的值,則過載無效,但編譯器不需要診斷。

template<typename T>
void f(T*) { }

template<typename T>
void f(T) { }

這是一個有效的過載,因為 T 和“T *”是不同的拼寫。但以下情況無效,無需診斷

template<typename T>
void f(T (*x)[sizeof(T) + sizeof(T)]) { }

template<typename T>
void f(T (*x)[2 * sizeof(T)]) { }