首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 模板類別編譯錯誤解析:尾隨返回型別語法與成員函數定義規則

     編輯:程式設計綜合問答

錯誤程式碼核心問題

// 錯誤 1:尾隨返回型別語法誤用
template <typename key,typename value>
BST<key, value>::put(pnode x,key k, value val)->pnode  // 編譯錯誤

// 錯誤 2:成員函數定義缺少返回型別
template <typename key, typename value>
BST<key, value>::get(pnode x, key k)->pnode  // 編譯錯誤

C++11 尾隨返回型別正確語法

auto 函數名(參數) -> 返回型別 僅適用於函數宣告/定義處,不適用於類別外部的成員函數定義。

正確的模板成員函數定義寫法

標準寫法(C++98 相容)

// put 成員函數定義
template <typename Key, typename Value>
typename BST<Key, Value>::pnode 
BST<Key, Value>::put(pnode x, Key k, Value val)
{
    if (x == nullptr) return new node(k, val);
    int cmp = compare(k, x->k);
    if (cmp < 0) x->left = put(x->left, k, val);
    else if (cmp > 0) x->right = put(x->right, k, val);
    else x->val = val;
    x->n = size(x->left) + size(x->right) + 1;
    return x;
}

// get 成員函數定義
template <typename Key, typename Value>
typename BST<Key, Value>::pnode 
BST<Key, Value>::get(pnode x, Key k)
{
    if (x == nullptr) return nullptr;
    int cmp = compare(k, x->k);
    if (cmp < 0) return get(x->left, k);
    else if (cmp > 0) return get(x->right, k);
    else return x;
}

關鍵修正點

  1. 返回型別前置:typename BST<Key, Value>::pnode(需 typename 關鍵字)
  2. 類別模板參數一致:定義處參數名建議與宣告一致(Key/Value vs key/value)
  3. 空指標判斷修正:if (x == nullptr) 而非 if (x = nullptr)(賦值 vs 比較)
  4. 使用 nullptr:C++11 建議取代 NULL/0

完整可編譯範例

#include <iostream>
#include <utility>

template <typename Key, typename Value>
class BST {
    struct node {
        Key k; Value val; int n;
        node *left, *right;
        node(Key k_, Value v_) : k(k_), val(v_), n(1), left(nullptr), right(nullptr) {}
    };
    using pnode = node*;
    
    pnode root = nullptr;
    
    int compare(Key k1, Key k2) {
        if (k1 < k2) return -1;
        if (k1 > k2) return 1;
        return 0;
    }
    
    int size(pnode x) const { return x ? x->n : 0; }
    
public:
    void put(Key k, Value val) { root = put(root, k, val); }
    std::pair<bool, Value> get(Key k) {
        pnode t = get(root, k);
        return t ? std::make_pair(true, t->val) : std::make_pair(false, Value());
    }
    
private:
    pnode put(pnode x, Key k, Value val);
    pnode get(pnode x, Key k);
};

// 類別外部定義(需在標頭檔或同一編譯單元)
template <typename Key, typename Value>
typename BST<Key, Value>::pnode 
BST<Key, Value>::put(pnode x, Key k, Value val) {
    if (!x) return new node(k, val);
    int cmp = compare(k, x->k);
    if (cmp < 0) x->left = put(x->left, k, val);
    else if (cmp > 0) x->right = put(x->right, k, val);
    else x->val = val;
    x->n = size(x->left) + size(x->right) + 1;
    return x;
}

template <typename Key, typename Value>
typename BST<Key, Value>::pnode 
BST<Key, Value>::get(pnode x, Key k) {
    if (!x) return nullptr;
    int cmp = compare(k, x->k);
    if (cmp < 0) return get(x->left, k);
    if (cmp > 0) return get(x->right, k);
    return x;
}

int main() {
    BST<int, std::string> tree;
    tree.put(5, "five");
    tree.put(3, "three");
    auto result = tree.get(3);
    if (result.first) std::cout << "Found: " << result.second << '\n';
}

Visual Studio 2015 特定注意事項

  • 支援 C++11 尾隨返回型別,但僅限函數本體定義處
  • 模板成員函數定義必須在標頭檔(或显式實例化)
  • 錯誤訊息 expected a type specifier 通常指向返回型別語法錯誤

總結

模板類別成員函數在類別外部定義時,必須使用標準返回型別前置語法,格式為:
typename Class<T>::ReturnType Class<T>::func(Params)。
尾隨返回型別(auto ... -> Type)不能用於類別外部成員函數定義。同時修正邏輯錯誤:比較運算子 == 勿誤寫為賦值 =。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved