2014-10-18 54 views
0

我發現我的代碼中的錯誤,我認爲應該用警告標記。用/ W4編譯,但不顯示任何警告(只關於未引用的形式參數)。如何檢測從布爾鑄造

#include <cstdio> 

void A(int item, unsigned int count, unsigned team_count) 
{ 
    printf("A, count, team count\n"); 
} 

void A(int item, unsigned int count=1, bool is_team=true) 
{ 
    printf("A, count, is_team\n"); 
    return A(item, count, is_team ? count : 0); 
} 

int main() 
{ 
    A(0, false); // <- bool to unsigned int 
    return 0; 
} 

這裏bool被轉換爲unsigned int。有什麼方法可以檢測到嗎? 試過Cppcheck但它沒有找到這個。

+0

你可以檢測你的函數的這種使用的唯一方法是重新表達它作爲一個函數模板,這通常是不切實際的。然而值得了解,因爲在某些特殊情況下它可能非常方便。提示:通過用枚舉替換布爾參數,使用函數變得更加清晰和安全。 – 2014-10-18 09:54:55

+1

這是一種煩人的語言「功能」。 – 2014-10-18 10:26:25

+0

嗯,我想你知道默認的參數值並不像你想象的那麼方便。特別是當有其他過載時。一個是好的。兩個或更多,嗯,不。一個體面的*皮棉*應該給你一個診斷。 – 2014-10-18 10:32:26

回答

1

標準說,這是可以接受的§4.7/ P4積分轉換:

If the source type is bool, the value false is converted to zero and the value true is converted to one.

關於如何檢測這個(因爲它是不是一個錯誤),並根據您的使用情況,您既可以做一些clang-tooling自己或寫上的線條與一些模板魔術扣的包裝:

#include <cstdio> 
#include <type_traits> 

template<typename T, typename U> 
void A(int item, T, U) { 
    static_assert(!std::is_same<T, unsigned int>::value || 
        (!std::is_same<U, unsigned int>::value && 
        !std::is_same<U, bool>::value), 
        "Something was wrong"); 
} 

template<> 
void A(int item, unsigned int count, unsigned int team_count) 
{ 
    printf("A, count, team count\n"); 
} 

template<unsigned int count = 1, bool is_team = true> 
void A(int item, unsigned int, bool) 
{ 
    printf("A, count, is_team\n"); 
    return A(item, count, is_team ? count : 0); 
} 

int main() 
{ 
    // A(0, false); - not acceptable 
    // A(0, 22); - not acceptable 
    A(0, static_cast<unsigned int>(2), false); 
    A(0, static_cast<unsigned int>(33), static_cast<unsigned int>(45)); 
    return 0; 
} 

Example

請注意,基本模板推理機制不需要C++ 11,雖然上面使用的一些函數可以。

+0

我加了這個: 'template <> inline bool AddItem(const Item *,bool){}' 它工作。顯示錯誤C2912:顯式專業化; 'bool Unit :: AddItem(const Item *,bool)'不是函數模板的特化。 – Tomashu 2014-10-18 11:25:31

+0

@Tomashu確保你有一個基本模板功能,使這項工作 – 2014-10-18 11:27:37

2

下面是一個例子,你如何能夠實現你想要

#include <iostream> 

void f(int) { std::cout << "f(int)" << std::endl; } 
void f(bool) = delete; 

int main() 
{ 
    f(true); 

    return 0; 
} 

編譯器錯誤

prog.cpp:8:10: error: use of deleted function ‘void f(bool)’ 
    f(true); 
     ^

應用到你的代碼的例子看起來像

#include <iostream> 

void A(int item, unsigned int count, unsigned team_count) 
{ 
    std::cout << "A, count, team count" << std::endl; 
} 

void A(int item, unsigned int count = 1, bool is_team = true) 
{ 
    std::cout << "A, count, is_team" << std::endl; 
    return A(item, count, is_team ? count : 0); 
} 

void A(int, bool) = delete; 

int main() 
{ 
    A(0, false); 

    return 0; 
} 

錯誤是什麼:

prog.cpp:18:14: error: use of deleted function ‘void A(int, bool)’ 
    A(0, false); 
      ^
+0

** + 1 **我不知道有人能做到這一點。謝謝! – 2014-10-18 12:03:41

+0

一個好主意。然而,一個順利。查看OP已標記其問題的VS的版本號。 – WhozCraig 2014-10-18 14:21:34

0

防止這種情況的一種非常安全的方法是將您的計數類型封裝在類中而不實現自動轉換。

class Count 
{ 
private: 
    int m_count; 
public: 
    explicit Count(int count) : m_count(count) 
    { 
     assert(m_count >= 0); 
    } 

    int Get() const { return m_count; } 
}; 

class TeamCount 
{ 
private: 
    int m_count; 
public: 
    explicit TeamCount(int count) : m_count(count) 
    { 
     assert(m_count >= 0); 
    } 

    int Get() const { return m_count; } 
}; 

// ... 

void A(int item, Count count, TeamCount team_count); 
void A(int item, Count count = Count(1), bool is_team = true); 

// ... 

A(0, false); // <- compiler error 
A(0, TeamCount(0), false); // <- compiler error 
A(0, Count(0), false); // OK 

你可以用你的其他原始類型參數做類似的事情。