16

enable_if型変換演算子で使用する機会はありますか? 戻り値の型とパラメーター リストの両方が暗黙的であるため、注意が必要です。

4

4 に答える 4

10

私が行ったちょっとした調査から (そして Johannes からの c++0x コメントを無視して)、私の答えは、あなたが何を求めているかによるということですenable_if。型から変換操作を存在させたい場合、Tまたは型から存在させたくない場合T、答えはノーのようです.C++ 03には方法がありません(Ugoが言ったように)。ただし、タイプに応じてオペレーターの動作enable_ifを変更する必要がある場合は、はい、有効なヘルパー関数を呼び出す回避策があります ( Matthieu が提案したように呼び出されます)。Tto<T>

#include<iostream>
#include<boost/utility/enable_if.hpp>
#include<boost/type_traits/is_class.hpp>

struct B{
    B(const B& other){}
    B(){}
};

struct A{
    template<class T>
    T to(typename boost::enable_if_c<not boost::is_class<T>::value, void*>::type = 0){
        std::clog << "converted to non class" << std::endl;
        return T(0);
    }
    template<class T>
    T to(typename boost::enable_if_c<boost::is_class<T>::value, void*>::type = 0){
        std::clog << "conveted to class" << std::endl;
        return T();
    }
    template<class T>
    operator T(){
        return to<T>();
    }
};

int main(){
    A a;
    double d = (double)a; // output: "converted to non class"
    B b = (B)(a); // output: "converted to class"
    return 0;
}

記録として、私はこれに数日間不満を感じてenable_ifいましたが、SFINAE ではなく、コンパイル時の動作の変更が必要であることに気付きました。また、これがまた必要な本当の理由であることに気付くかもしれませんenable_if。ただの提案です。

(これはC++98時代の回答であることに注意してください)

于 2011-09-29T23:47:28.473 に答える
2

実際、私は方法を見つけました。未使用のプライベート クラスを使用して、存在しないはずの変換をマークし、 を使用boost::mpl::if_して、NoConversion への変換を生成するか、目的の型への変換を生成するかを選択します。

class A {
    class NoConversion { };
    template<class B> operator typename boost::mpl::if_<Cond, B, NoConversion>::type() const;
}
于 2013-01-10T21:56:26.520 に答える
2

質問の理論的な興味は理解できますが、個人的には変換演算子の使用をできるだけ控えています。

私が一貫して使用する唯一のものは、スマートポインターまたはプロキシ用の疑似ブール値への変換 (Safe Bool イディオムを使用) です。

変換を容易にしたい場合は、次のようなものを好みます。

template <class T>
T to() const;

これは、変換演算子の (署名に関する) 制限の影響を受けず、明示的な呼び出しを必要としますが、それは少し明確だからです。

于 2010-06-20T10:41:41.127 に答える
2

ドキュメントを参照てください :
変換演算子のイネーブラーを指定する方法がないようです。ただし、変換コンストラクターは、追加のデフォルト引数としてイネーブラーを持つことができます。

于 2010-06-19T19:59:19.453 に答える