2009-10-28 51 views
9

我在C++中重載方法時遇到了一些麻煩。 作爲問題的一個例子,我有一個包含很多方法的類被重載,並且每個方法都有一個具有不同數據類型的參數。 我的問題:在類中是否存在這些方法應該出現的特定順序,以確保根據其參數數據類型調用正確的方法?函數/方法重載C++:數據類型混淆?

class SomeClass{ 
    public: 
    ... 
    void Method(bool paramater); 
    void Method(std::string paramater); 
    void Method(uint64_t paramater); 
    void Method(int64_t paramater); 
    void Method(uint8_t paramater); 
    void Method(int8_t paramater); 
    void Method(float paramater); 
    void Method(double paramater); 
    void Method(ClassXYZ paramater); 
} 

我注意到,因爲在運行時出現了問題:

Method("string"); 

有人呼籲:

Method(bool paramater); 

回答

5

的字符串文字"string"具有類型const char[]可以含蓄轉化爲bool。這是您的一個重載函數的最佳轉換候選,儘管它不可​​能是最有用的函數。

如果您的意圖是讓字符串文本由過載處理,請參閱std::string,那麼您需要添加一個過載文件並執行const char*並使實現調用std::string版本。

+0

這是完全惱人的。這個解決規則不能達到一個如此基本的概念。也許OP「通過聲明訂單」直觀的方法會做得更好。 – 2012-12-08 01:20:12

4

訂單無關緊要。這裏的問題是,當你調用

Method("string"); 

你傳遞一個const char []。這將被隱式轉換爲bool。你想要做的是明確地傳遞一個std :: string:

Method(std::string("string")); 
+0

不要投;構造! std :: string(「string」) (或者重載char *就像上面說的那樣) – 2009-10-28 11:32:55

+0

當然;編輯,謝謝。 – Tomas 2009-11-03 15:33:33

23

該命令沒有區別。要調用的方法是通過分析參數的類型並將它們與參數類型進行匹配來選擇的。如果沒有完全匹配,則選擇最佳匹配方法。在你的情況下,它恰好是bool方法。

您正在提供類型const char[7]的參數。根據C++超載規則,此處的最佳路徑是使const char[7]衰減至const char *,然後使用標準轉換將其轉換爲bool。轉換爲std::string的路徑被認爲更差,因爲它將涉及從const char *std::string的用戶定義轉換。通常,用戶定義的轉換將重載解析過程丟失到標準轉換。這也是你的情況。

如果您需要std::string版本在這裏呼籲,爲const char *類型std::string型明確

void Method(const char *paramater /* sic! */) 
{ 
    Method(std::string(paramater)); 
} 
+1

未定義 - >用戶定義? – jalf 2009-10-28 10:36:53

+0

固定。謝謝。 – AnT 2009-10-28 10:40:22

1

正如查爾斯已經指出的那樣提供一個明確的過載,並委託調用std::string版本通過轉換參數,這是由於不需要的隱式轉換造成的。如果你想避免這種情況,使用的std :: string構造函數: Method(std::string("string")); 或鑄造它的std :: string:

Method(static_cast<std::string>("string")); 

然而,您聲明的順序並不重要。同時檢查您的單詞「參數」的拼寫;)

1

除了字符串的問題,還有另一個。 int64_t和int8_t是(通常)typedefs。由於typedef只是別名,所以它們可能會引用相同的類型,在這種情況下,重載將不起作用。但是這對你來說不太可能。只是想提到它。

2

不回答你的問題,但出於好奇,是否有隱藏的原因,不使用模板方法,而是爲每種類型定義重載版本?

class SomeClass 
{ 
    public: 
    ... 
    template <typename T> 
    void Method(T paramater); 
}; 
+0

這很好,因爲它會禁用自動轉換開始變得怪異。您也可以爲您打算支持的少數專業化定義您的方法。 – 2009-11-03 15:44:46

1

您可以添加顯式關鍵字,以便採取預定的參數。