5

を使用する関数を前方宣言するのに問題がありますboost::enable_if。次のコードではコンパイラ エラーが発生します。

// Declaration
template <typename T>
void foo(T t);

// Definition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}

int main()
{
    foo(12);
    return 0;
}

コンパイル時に、「foo へのあいまいな呼び出し」エラーが発生します。の定義によるとenable_if、'type' typedefvoidは条件が true の場合に対応するため、私が見る限り、2 つのシグネチャはfoo一致します。なぜコンパイラはそれらが異なると考えるのですか?また、前方宣言する正しい方法はありますかfoo(できれば、その部分を繰り返さないでenable_ifください)?

4

2 に答える 2

3

これは enable_if だけの問題ではありません。次のコードを使用すると、Visual Studio と gcc で同じエラーが発生します。

struct TypeVoid {
  typedef void type;
};

template<typename T>
void f();

template<typename T>
typename T::type f() {
}

int main()
{
  f<TypeVoid>();
  return 0;
}

主な問題は、戻り値の型 (インスタンス化前) がテンプレート関数のシグネチャの一部であることだと思います。詳細については、こちらをご覧ください。

コードに関して、宣言が定義を参照している場合は、両方を一致させる必要があります。

// Declaration       
template <typename T>       
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t);       

// Definition       
template <typename T>       
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)       
{       
}

宣言が別の関数を参照している場合、コンパイラはintに対して正しいものを選択できません。どちらも有効であるためです。ただし、 disable_ifを使用してintの最初のものを無効にすることができます。

// Other function declaration
template <typename T>
typename boost::disable_if<boost::is_same<T, int> >::type foo(T t);

// Defition
template <typename T>       
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)       
{       
}
于 2010-01-13T12:34:52.590 に答える
1

問題は、宣言と定義が一致しないことです。

enable_if解決策は、宣言にまったく同じ署名とビットを含めることです。

#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>

// Declaration
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t);

// Definition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}

int main()
{
    foo(12);
    return 0;
}

これは VC2008 で問題なくコンパイルされます。

于 2010-01-09T15:49:16.913 に答える