この問題についての背景はありません。SFINAEのユーザー定義変換の場合
SFINAEを(直接または間接的にtype_traitsで)使用して、既存の関数、メンバー関数などをチェックする方法はたくさんあります。しかし:
最初の質問:クラスが特定のユーザー定義の変換演算子を実装しているかどうかを確認する方法はありますか?
私が何を意味するかを説明するために、このコードを検討してください。私は、任意のアサーション失敗することなく、このコードを実行したい:
#include <type_traits>
#include <cassert>
struct NotADouble {
};
struct Double {
// explicit or not - you decide
explicit operator double() {
return 1.;
}
};
// CORRECT THIS: ...
template<typename T,
class = decltype(static_cast<double>(std::declval<T>()))>
int f(T) {
return 1;
}
int f(...) {
return 2;
}
// ... UNTIL HERE
int main() {
assert(f(NotADouble()) == 2);
assert(f(Double()) == 1);
assert(f(3.) == 2);
assert(f(3) == 2);
assert(f(3.f) == 2);
}
T
からdouble
の任意の標準的な変換シーケンスがあるかどうかf
チェックの現在の実装で、Iは、これがこの場合にstd::is_convertible
と同じであると仮定する。
もう1つのアプローチは、最初の2つのテストを受け入れる次の実装です。
template<typename T>
int f(T, double (T::*)() = nullptr) {
return 1;
}
int f(...) {
return 2;
}
質問2:NotADoubleは、任意の変換演算子を実装していませんが、このメンバ関数ポインタを許可しているようです。したがって、正確にはdouble (T::*)()
とは何ですか、なぜそれはどのクラスにも存在しますか?
私が試したのと同様のテストがありましたが、参照がなく、明らかに十分ではありませんでした。 – overseas
@ user3445587あなたは 'のアドレス演算子(&)を意味します。はい残念ながら、メンバ関数の参照を行う方法はありませんが、これは明らかに欠点ですが、直接的にはC++のメソッド呼び出しの構文によるものです。例えば。 'a.foo();' 'foo'をどのように解釈すべきでしょうか?スコープ内で使用可能な 'a'またはメンバ関数リファレンスのメンバ関数として...? –