enable_ifとコンバージョンオペレーター?
-
28-09-2019 - |
質問
使用する機会 enable_if
タイプ変換オペレーターで?リターンタイプとパラメータリストの両方が暗黙的であるため、トリッキーなようです。
解決
dixit the ドキュメンテーション:
コンバージョンオペレーターのイネーブラーを指定する方法はないようです。ただし、コンストラクターを変換すると、イネーブラーが追加のデフォルトの引数として持つことができます。
他のヒント
私がした小さな研究から(そしてヨハネスからのC ++ 0xコメントを無視している)、私の答えはあなたが何を望んでいるかによって異なるということです enable_if
にとって。変換操作が必要な場合 T
タイプから存在するかどうか T
それから、答えはノーのように思われますが、C ++ 03には方法はありません(Ugoが言ったように)。しかし、あなたが必要な場合 enable_if
変更する 行動 オペレーターのタイプに応じて T
それからはい、有効なヘルパー関数を呼び出す回避策があります(呼ばれます to<T>
Matthieuが示唆したように)。
#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 ERAの答えであることに注意してください)
私は質問に対する理論的な関心を理解することができますが、私は個人的に可能な限り変換オペレーターを使用することを控えています。
一貫して使用した唯一のものは、スマートポインターまたはプロキシ用の擬似ブール(セーフブールイディオムを使用)への変換です。
コンバージョンを促進したい場合、私は次のようなものに沿って何かを好みます。
template <class T>
T to() const;
コンバージョン演算子の制限(署名の用語で)に悩まされておらず、少し明確であるという理由だけで、明示的な呼び出しが必要です。
実際、私は道を見つけました。プライベートで未使用のクラスを使用して、存在しないはずの変換をマークし、使用します boost::mpl::if_
Noconversionへの変換を生成するか、目的のタイプに変換するかを選択します。
class A {
class NoConversion { };
template<class B> operator typename boost::mpl::if_<Cond, B, NoConversion>::type() const;
}