我在代码中发现错误,我认为应该标记为警告。用/ 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 :(得分: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;
}
请注意,基本模板推导机制不需要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
你可以用其他原始类型参数做类似的事情。