これらが有効であるようにクラスを書くことは可能ですか:
Foo a;
Foo b = 0;
Foo c = b;
Foo d(0);
Foo e(1);
Foo f = Foo(1);
しかし、これらはそうではありません:
int x;
Foo a = x;
Foo b = 1;
Foo c = 2;
//etc
基本的に、私のルールは「定数0
は暗黙的に に変換できFoo
ますが、他の値は変換できません」です。
これらが有効であるようにクラスを書くことは可能ですか:
Foo a;
Foo b = 0;
Foo c = b;
Foo d(0);
Foo e(1);
Foo f = Foo(1);
しかし、これらはそうではありません:
int x;
Foo a = x;
Foo b = 1;
Foo c = 2;
//etc
基本的に、私のルールは「定数0
は暗黙的に に変換できFoo
ますが、他の値は変換できません」です。
Foo e(1);
int を引数として取り、Foo の非明示的なコンストラクターを呼び出します。基本的に、この行は、この int コンストラクターを使用して int を Foo に変換しようとすることで、同じことを行います。
Foo b = 1;
その int の特定の値が直接処理されるのを防ぐことはできません。コンストラクターがある場合explicit
、次の行も書くことができません。
Foo b = 0;
gx_ は、0 を std::nullptr_t に変換できると正しく述べています。以下は、あなたの意図に関して機能します。
Foo(std::nullptr_t x) : member(0) { }
explicit Foo(int c) : member(c) { }
// ...
Foo a = 0; // compiles
Foo b = 1; // doesn't compile
// Note:
int do_stuff (void) { return 0; }
Foo c = do_stuff(); // doesn't compile
私はまだ C++11 の右辺値セマンティクスを完全に習得していないことを認めますが、これはあなたが望むことをするようです:
class Foo
{
public:
Foo(int&&) {}
};
int main()
{
Foo a(123);
int x = 123;
Foo b(x); // error here, line 11
return 0;
}
結果:
prog.cpp:11: エラー: 'int' 左辺値を 'int&&' にバインドできません</p>
このコードに気付いていない警告がある場合、またはそうではないことを安心していただける場合は、コメントを歓迎します。
私が持っていた1つのアイデアは次のとおりです。
Foo(const uint32_t c) : member(0) { static_assert(c == 0, "Nope"); }
explicit Foo(uint32_t c) : member(c) { }
これは賢明に動作しますか?