enable_if
型変換演算子で使用する機会はありますか? 戻り値の型とパラメーター リストの両方が暗黙的であるため、注意が必要です。
4 に答える
私が行ったちょっとした調査から (そして Johannes からの c++0x コメントを無視して)、私の答えは、あなたが何を求めているかによるということですenable_if
。型から変換操作を存在させたい場合、T
または型から存在させたくない場合T
、答えはノーのようです.C++ 03には方法がありません(Ugoが言ったように)。ただし、タイプに応じてオペレーターの動作enable_if
を変更する必要がある場合は、はい、有効なヘルパー関数を呼び出す回避策があります ( Matthieu が提案したように呼び出されます)。T
to<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時代の回答であることに注意してください)
実際、私は方法を見つけました。未使用のプライベート クラスを使用して、存在しないはずの変換をマークし、 を使用boost::mpl::if_
して、NoConversion への変換を生成するか、目的の型への変換を生成するかを選択します。
class A {
class NoConversion { };
template<class B> operator typename boost::mpl::if_<Cond, B, NoConversion>::type() const;
}
質問の理論的な興味は理解できますが、個人的には変換演算子の使用をできるだけ控えています。
私が一貫して使用する唯一のものは、スマートポインターまたはプロキシ用の疑似ブール値への変換 (Safe Bool イディオムを使用) です。
変換を容易にしたい場合は、次のようなものを好みます。
template <class T>
T to() const;
これは、変換演算子の (署名に関する) 制限の影響を受けず、明示的な呼び出しを必要としますが、それは少し明確だからです。
ドキュメントを参照してください :
変換演算子のイネーブラーを指定する方法がないようです。ただし、変換コンストラクターは、追加のデフォルト引数としてイネーブラーを持つことができます。