0

パラメータを取る関数があります。「生の」数値の場合もあれば、数値に関するメタ情報を含むホルダー クラスにラップされた数値の場合もあります。このような2つのケースを区別できます

template<class T>
struct Holder
{
};

template<class T>
void f1(T)
{
}

template<class T>
void f1(Holder<T>)
{
}

ただし、ユーザーが何を望んでいるかに応じて、生の番号または所有者のいずれかを返したいと考えています。関数を呼び出すときに、ユーザーがテンプレート パラメーターを明示的に指定する必要があることはわかっています。それでいいのですが、できれば同じ名前の関数が欲しいです。このようなもの

template<class T>
T f1()
{
    return T();
}

template<class T>
Holder<T> f1()
{
    return T();
}

f1<int>();ただし、それをorとして呼び出すとf1<Holder<int>>();error: ambiguous call to overloaded function

関数名を変更せずにこれは可能ですか?(そうでなければ大したことではありません、ただ気になるだけです)

4

3 に答える 3

3

SFINAE( std::enable_if) を使ったアプローチとは別に、部分特殊化を使うことができます。関数テンプレートでは部分的な特殊化ができないため、次のように少し手間がかかります。

template <typename T>
struct f1_specialization {
    static T f1() { ... }
};
template <typename T>
struct f1_specialization<Holder<T>> {
    static Holder<T> f1() { ... }
};
template <typename T>
T f1() { return f1_specialization<T>::f1(); }

どちらのアプローチも多かれ少なかれ明確であり、両方とも機能するはずです。

于 2013-09-16T16:17:28.080 に答える
1

はい、可能enable_ifです。しかし、それは恐ろしいです。これは C++11 で書きます。

template <typename T> struct is_holder {
  static constexpr bool value = false;
};
template <typename T> struct is_holder<Holder<T>> {
  static constexpr bool value = true;
};

template <typename T,
          typename = typename std::enable_if<is_holder<T>::value>::type>
T f1() {
  // T is Holder<U>
}

template <typename T,
          typename = typename std::enable_if<!is_holder<T>::value>::type>
T f1() {
  // T is not Holder<U>
}

もちろん、呼び出すときにテンプレート引数を明示的に指定する必要があります。

于 2013-09-16T16:12:04.063 に答える
0

decltypeをチェックアウトします。

    template <class T, class U>
    auto add(T t, U u) -> decltype(t + u);
于 2013-09-16T17:06:09.433 に答える