4

C++ で (C スタイルの) キャストをオーバーライドすることは可能ですか?

コードがあるとします

double x = 42;
int k = (int)x;

2 行目のキャストで、私が書いたコードを実行できますか? 何かのようなもの

// I don't know C++
// I have no idea if this has more syntax errors than words
operator (int)(double) {
    std::cout << "casting from double to int" << std::endl;
}

私が尋ねる理由は、「gcc や clang に明示的なキャストを警告させる方法はありますか?」という質問のためです。そして私の提案があります。

4

4 に答える 4

5

§ 12.3.1/1 「クラス オブジェクトの型変換は、コンストラクターおよび変換関数によって指定できます。これらの変換はユーザー定義の変換と呼ばれ、暗黙の型変換 (条項 4)、初期化 (8.5)、および明示的な型変換 (5.4、5.2.9)」。

はい、変換を行うことができますが、一方または両方がユーザー定義型である場合に限り、doubletoの変換を行うことはできませんint

struct demostruct {
    demostruct(int x) :data(x) {} //used for conversions from int to demostruct
    operator int() {return data;} //used for conversions from demostruct to int
    int data;
};

int main(int argc, char** argv) {
    demostruct ds = argc; //conversion from int to demostruct
    return ds; //conversion from demostruct to int
}

Robᵩ が指摘したように、explicitこれらの変換関数のいずれかにキーワードを追加できます。これには、ユーザーが暗黙的に変換するのではなく、コード内で a(demostruct)argcまたはlike を使用して明示的にキャストする必要があります。(int)ds同じ型との間で変換する場合は、通常、一方または両方を asexplicitにするのが最善です。そうしないと、コンパイル エラーが発生する可能性があります。

于 2012-04-25T17:01:19.407 に答える
4

はい。ただし、自分のタイプのみです。これを見てください:

#include <iostream>
struct D {
  // "explicit" keyword requires C++11
  explicit operator int() { std::cout << __FUNCTION__ << "\n"; }
};

int main () {
  int i;
  D d;
  //i = d;
  i = (int)d;
}

したがって、 を作成することはできませんが、作成するdouble::operator int()ことはできますMyDouble::operator int()

于 2012-04-25T17:00:02.993 に答える
3

組み込み型の演算子をオーバーロードすることはできませんが、ユーザー定義型の変換演算子を作成できます。

struct Double {
    double value;
    operator int() const {
        shenanigans();
        return value;
    }
};

あなたの質問は、コードで明示的なキャストを見つける必要性から生じたものであるため、C++ には明示的なキャスト演算子があることにも注意してください。これらは C スタイルのキャストよりも明確であるだけでなく、非常に検索しやすい:

static_cast<T>(x)      // Cast based on static type conversion.
dynamic_cast<T>(x)     // Cast based on runtime type information.
const_cast<T>(x)       // Add or remove const or volatile qualification.
reinterpret_cast<T>(x) // Cast between unrelated pointer and integral types.
于 2012-04-25T16:59:22.077 に答える
1

他の型への変換は、C++ ではオーバーロード可能な演算子です (ここにいくつかの例があります) が、この事実は役に立ちません。

Stroustrupは、言語を拡張可能にすることを望んでいましたが、変更可能ではありませんでした。したがって、演算子のオーバーロードは操作を新しい型に拡張するだけで、古い型で何が起こるかを再定義することはできません。

"しかし、ばかげたことを避けるために、組み込み型の組み込み演算子に新しい意味を提供することは (まだ) 許可されていません。したがって、言語は拡張可能のままですが、変更可能ではありません。 "

于 2012-04-25T16:58:13.007 に答える