3

変換コンストラクターと変換演算子の両方を持つコードがあります。

#include <iostream>
struct ClassFloat;

struct ClassInt{
    int value;
    ClassInt(int c) : value(c){std::cout << "From integer\n";};
    ClassInt(ClassFloat x);
    //explicit ClassInt(ClassFloat x);
};

struct ClassFloat{
    float val;
    explicit operator ClassInt() {std::cout << "Conversion operator called\n"; return ClassInt{999};}
    //operator ClassInt() { std::cout << "Conversion operator called\n"; return ClassInt{999};}
};

ClassInt::ClassInt(ClassFloat x){
    std::cout << "Conversion constructor called!\n";
    value = (int)x.val;
}

int main(){
    ClassFloat floatObj{3.5f};
    ClassInt instance1 = floatObj;           // (1)
    ClassInt instance2 = (ClassInt)floatObj; // (2)
    return 1;
}
  1. 両方とも明示的でない場合。最初の式があいまいであるというコンパイラ エラーが発生します。2 番目の式は、コンストラクターを呼び出します。
  2. 演算子のみが明示的である場合、両方の変換でコンストラクターが使用されます。
  3. コンストラクターのみが明示的である場合、2 番目の変換はコンストラクターを呼び出し、最初の変換は演算子を使用します。
  4. 両方が明示的である場合、2 番目の式のみをコンパイルできます。コンストラクターを使用します。

2 番目のシナリオの 2 番目の式で変換演算子が呼び出されなかった理由がわかりませんでした。

また、4 番目のシナリオ (最初のシナリオと同様) であいまいなエラーが発生することを期待していましたが、コンストラクターが選択されました。

-pedantic および -std=c++17 フラグを指定して g++ 7.4.0 を使用してコンパイルしました。

4

1 に答える 1