0

たとえば、次のテンプレート関数があります。

template<class IntType = typename boost::uintmax_t>
IntType someFunnyFunc(IntType x, IntType y, IntType z) { ... }

今、私は次のコードを持っています:

int main() {
    short a=1, b=2, c=3;
    someFunnyFunc(a, b, c);
    return 0;
}

すべてのコンパイラが関数を生成しますか

boost::uintmax_t someFunnyFunc(boost::uintmax_t x, boost::uintmax_t y, boost::uintmax_t z) { ... }

、shortはboost :: uintmax_tに変換できるため、または一部のコンパイラは生成します

short someFunnyFunc(short x, short y, short z) {...}

私のアルゴリズムはループを使用しているため、これが必要です。大きな整数ではなく短い整数を使用すると、ループが頻繁に発生します。

あなたは、なぜ私が単にboost::uintmax_t someFunnyFunc(boost::uintmax_tx, boost::uintmax_t y, boost::uintmax_tz) { ... }自分自身を定義してそれで終わらせないのかと尋ねるかもしれません。これを行うのは、プラットフォームで直接サポートされていないより大きな整数を使用できるように、カスタム整数型を使用できるようにするためです。

編集: これは私の問題を解決できますか:

template<class IntType>
IntType someFunnyFunc(IntType x, IntType y, IntType z) { ... }

boost::uintmax_t someFunnyFunc(boost::uintmax_t x, boost::uintmax_t y, boost::uintmax_t z) {
    return someFunnyFunc<boost::uintmax_t>(x, y, z);
}
4

1 に答える 1

2

コンパイラーは型変換を実行しません。それらは生成します:

short someFunnyFunc(short x, short y, short z)

簡単に言うと、コンパイラは「抵抗が最も少ないパス」を選択します。型変換の実行には「抵抗」がありますが、引数に完全に一致する関数シグネチャを生成することには「抵抗」はありません。

「抵抗」が等しいパスが複数ある場合は、あいまいな(または一致する関数がない)エラーが発生する可能性があります(コンパイラはどのパスを使用する必要がありますか?)。たとえば、、、、を渡そうとするshortint、実行しようとしていることに適切に一致する署名がないためlongエラーが発生します。コンパイラは関数の適切な型を推測できません。これは、いくつかの可能性があり、どれも「最良」ではないためです。

編集:いいえ、それはあなたの問題を解決しません。sを渡す場合short、コンパイラはテンプレート化された関数を選択します(そしてを使用しますIntType = short)。

使用したいが引数を渡しsomeFunnyFunc<boost::uintmax_t>(short_1, short_2, short_3);たい場合は、これを行うことができます。次のこともできます。boost::uintmax_tshort

template<class IntType>
IntType someFunnyFunc(IntType x, IntType y, IntType z) { ... }

// If you try to pass shorts, the compiler will opt for this version:
boost::uintmax_t someFunnyFunc(short x, short y, short z) {
    return someFunnyFunc<boost::uintmax_t>(x, y, z);
}

使用したいboost::uintmax_tが、それでもshortsを渡すと仮定します。

于 2013-02-23T20:01:21.547 に答える