我知道关键字explicit可用于防止隐式转换.
例如
Foo {
 public:
 explicit Foo(int i) {}
}
我的问题是,在什么条件下,应该禁止隐含转换?为什么隐式转换有害?
Bri*_*ndy 11
使用explicit时,你会喜欢一个编译错误.
explicit 仅当构造函数中有一个参数时才适用(或许多第一个参数只有没有默认值的参数). 
你可能希望explicit在程序员错误地构造一个对象的任何时候使用该关键字,认为它可能会做一些它实际上没做的事情.
这是一个例子:
class MyString
{
public:
    MyString(int size)
        : size(size)
    {
    }
     //... other stuff
    int size;
};
使用以下代码,您可以执行此操作:
int age = 29;
//...
//Lots of code
//...
//Pretend at this point the programmer forgot the type of x and thought string
str s = x;
但是调用者可能意味着在MyString变量中存储"3"而不是3.最好得到一个编译错误,这样用户可以先调用itoa或x变量上的其他转换函数.
将为上述代码生成编译错误的新代码:
class MyString
{
public:
    explicit MyString(int size)
        : size(size)
    {
    }
     //... other stuff
    int size;
};
编译错误总是优于错误,因为它们可以立即显示以供您更正.
它引入了意想不到的临时工:
struct Bar
{
    Bar();      // default constructor
    Bar( int ); // value constructor with implicit conversion
};
void func( const Bar& );
Bar b;
b = 1; // expands to b.operator=( Bar( 1 ));
func( 10 ); // expands to func( Bar( 10 ));
一个现实世界的例子:
class VersionNumber
{
public:
    VersionNumber(int major, int minor, int patch = 0, char letter = '\0') : mMajor(major), mMinor(minor), mPatch(patch), mLetter(letter) {}
    explicit VersionNumber(uint32 encoded_version) { memcpy(&mLetter, &encoded_version, 4); }
    uint32 Encode() const { int ret; memcpy(&ret, &mLetter, 4); return ret; }
protected:
    char mLetter;
    uint8 mPatch;
    uint8 mMinor;
    uint8 mMajor;
};
VersionNumber v = 10;几乎可以肯定是一个错误,所以explicit关键字需要程序员输入VersionNumber v(10);- 如果他或她使用一个体面的IDE  - 他们会通过它想要的IntelliSense弹出窗口注意到encoded_version.