如何检测bool中的强制转换

时间:2014-10-18 09:42:02

标签: c++ visual-studio-2008

我在代码中发现错误,我认为应该标记为警告。用/ 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,但没有找到。

3 个答案:

答案 0 :(得分: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 );
              ^

答案 1 :(得分:1)

标准认为这是可以接受的§4.7/ p4 积分转换:

  

如果源类型为bool,则将值false转换为零,将值true转换为一。

关于如何检测这个(因为它不是一个错误)并且取决于你的用例,你可以自己做一些clang-tooling或者在以下行中写一些包含模板扣除魔法的包装器: p>

#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,尽管上面使用了一些函数。

答案 2 :(得分: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

你可以用其他原始类型参数做类似的事情。