2011-09-26 57 views
14

我正在爲類的C++程序工作,我的編譯器抱怨「模糊」的函數調用。我懷疑這是因爲有幾個函數用不同的參數定義。如何解決「模棱兩可」的函數調用?

如何告訴編譯器我想要哪一個?除了特定於案例的修補程序之外,是否有一個通用規則,例如類型轉換,可以解決這些類型的問題?

編輯:

就我而言,我打過電話abs()一個cout聲明的內部,通過兩個double秒。

cout << "Amount is:" << abs(amountOrdered-amountPaid);

EDIT2:

我包括這三個頭:

#include <iostream> 
#include <fstream> 
#include <iomanip> 

using namespace std; 

EDIT3:

我已經完成了程序沒有這個代碼,但爲了跟隨這個問題的興趣上,我已經轉載了這個問題。逐字錯誤是:

調用'abs'是不明確的。

編譯器提供了三個版本的abs,每個版本都採用不同的數據類型作爲參數。

+1

您能否從您的代碼中展示一個示例? –

+1

這真的取決於情況。你需要發佈代碼,如果編譯器錯誤包含哪些函數是候選者(最近的GCC),那也有幫助。 –

+2

也很好,將包括哪些標題。 – mkb

回答

19

什麼事是你已經包括<cstdlib>(間接地,因爲它包括iostream)以及using namespace std;。該標題聲明std中的兩個函數,名稱爲abs()。一個需要並返回long long,另一個返回long。此外,還有全局名稱空間中的一個(返回int),它來自<stdlib.h>

修復:好吧,需要雙倍的abs()<cmath>,這實際上會給你你想要的答案!

+4

TL; DR:避免使用名稱空間。 –

+0

@MatthieuM。,即使在iOS SDK中使用'std :: abs()',我也看到了這個(sematic)錯誤。當我刪除'std ::'並僅使用'abs()'時,該錯誤就被刪除了。 – iammilind

+1

是的,問題更多的是由於自動數字類型轉換。 – mkb

-1

不知道這是爲什麼不叫ABS的版本INT,但你可以嘗試的類型轉換表達式(amountOrdered - amountPaid)爲INT,即

cout <<"Amount is: "<< abs((int)(amountOrdered - amountPaint)); 
+1

「不知道爲什麼這不是調用abs的整數版本」可能是因爲'amountOrdered'和'amountPaid'是雙打嗎? –

+0

你是對的,不知道我在想什麼! @OP編譯器混淆了要調用哪個版本(long或double),因爲它不確定它是否需要將long類型轉換爲long或從double類型轉換爲int。 Mr.Martinho先生 - 我想我的解決方案將幫助編譯器決定調用哪個版本。所以我有點正確:) –

4

通過<cstdlib>包括的abs函數被重載爲intlonglong long。由於您提供了double作爲參數,因此編譯器沒有精確的擬合,所以它會嘗試將double轉換爲abs接受的類型,但不知道它是否應該嘗試將其轉換爲int,longlong long,因此它是不明確的。

但是,您可能確實需要abs需要double並返回double。爲此,您需要包含<cmath>。由於double參數完全匹配,編譯器不會抱怨。

看起來,<cstdlib>自動包含在其他標題不應該發生的時候。編譯器應該給出error: ‘abs’ was not declared in this scope或類似的東西。

+0

'abs'不是函數模板。給出模板參數將不起作用。 'static_cast (bar)'會編譯(但仍然給出錯誤的答案) – mkb

+0

@mkb - 謝謝,我忘記了它們只是重載而不是模板函數專精。編輯了那部分。 – JohnPS

2

嘗試使用<cmath>中定義的fabs。它需要float,doublelong double作爲參數。在<cmath><cstdlib>中定義了abs。差異是abs(int),abs(long)abs(long long)<cstdlib>中定義,而其他版本在<cmath>中定義。

+0

解決此類錯誤的常見解決方案是使用庫的C++版本而不是標準C庫,例如:cstdio而不是stdio.h。 C++庫的名稱前綴爲'c',不存在'.h' – Andiana

相關問題