c++ - Risoluzione di sovraccarico per funzioni ereditate



templates inheritance (1)

Voglio avere una struttura che accetta un numero arbitrario di lambda e che funge da punto di chiamata centrale per tutti i loro operatori di chiamata.

Se l'operatore di chiamata viene richiamato con un elenco di argomenti che non corrisponde a nessuna delle lambda fornite in fase di costruzione, è necessario chiamare un operatore di chiamata predefinito.

Ho pensato che il seguente codice avrebbe realizzato esattamente questo. L'operatore di chiamata per ogni lambda viene "sollevato" nella classe Poc tramite.

template <typename ...Lambdas>
struct Poc : Lambdas...
{
    using Lambdas::operator() ...; // Lift the lambda operators into the class

    template <typename ...Ts>
    auto operator() (Ts...)
    {
        std::cout << "general call" << std::endl;
    }
};

// Deduction guide
template <typename ...Ts>
Poc(Ts... ts)->Poc<Ts...>;

int main()
{
    auto l_int = [](int) {std::cout << "int" << std::endl; };

    Poc poc{l_int};
    poc(1);//calls the default operator. why?

    return 0;
}

Quando non ho l'operatore di chiamata predefinito nella struttura, tutto funziona come previsto (con elenchi di argomenti validi). Se lo aggiungo allo struct (come nel codice sopra), l'operatore predefinito viene chiamato ogni volta, indipendentemente dagli argomenti con cui lo chiamo.

A mio avviso, gli operatori lambda-call e l'operatore struct (predefinito) sono presenti nello stesso ambito. Pertanto, dovrebbero essere esaminati tutti per la risoluzione del sovraccarico. Poiché l'operatore lamdba è più specifico dell'operatore predefinito generico, dovrebbe essere scelto.

Apparentemente non è così. Perché?

Ho testato su Microsoft Visual C ++ , Clang e GCC (tutti nelle loro ultime versioni).

Modificare:


È semplice quando lo vedi: il tuo operatore non è qualificato, mentre quello di lambda lo è (a meno che tu non definisca il lambda come mutable ). Quindi, è una corrispondenza migliore per la tua istanza non const di Poc .

Aggiungi la const mancante:

auto operator() (Ts...) const




overloading