Domanda

Ho qualche problema in avanti dichiarando una funzione che utilizza boost::enable_if : il seguente pezzo di codice mi dà un errore di compilazione:

// 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;
}

Quando si compila, ottengo un errore "chiamata ambigua alla foo". Secondo la definizione di enable_if, il 'tipo' typedef corrisponde void quando la condizione è vera, quindi, per quanto posso vedere, le due firme di partita foo. Perché il compilatore pensa sono diversi, e c'è un modo corretto per inoltrare dichiarare foo (preferibilmente senza ripetere la parte enable_if)?

È stato utile?

Soluzione

Questo non è solo un problema con enable_if. È possibile ottenere lo stesso errore su Visual Studio e gcc con il seguente codice:

struct TypeVoid {
  typedef void type;
};

template<typename T>
void f();

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

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

Credo che il problema principale è che il tipo di ritorno (prima esemplificazione) fa parte della firma di una funzione template. Ci sono più informazioni qui .

Per quanto riguarda il codice, se la dichiarazione si riferisce alla definizione, si dovrebbe abbinare entrambi:

// 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)       
{       
}

Se la dichiarazione si riferisce ad una funzione diversa, il compilatore non sarebbe mai in grado di scegliere quello corretto per int s, perché entrambi sono validi. Tuttavia, è possibile disattivare il primo per int s utilizzando disable_if :

// 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)       
{       
}

Altri suggerimenti

Il problema è che la dichiarazione e la definizione non corrispondono.

La soluzione è che la dichiarazione deve contenere l'esatto firma stessa, e il bit del 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;
}

Questa compila bene su VC2008.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top