"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > ## Por que a herança múltipla com classes base de modelo causa ambigüidade na resolução de funções de membro?

## Por que a herança múltipla com classes base de modelo causa ambigüidade na resolução de funções de membro?

Publicado em 2024-11-08
Navegar:501

## Why Does Multiple Inheritance with Template Base Classes Cause Ambiguity in Member Function Resolution?

Ambiguidade na desambiguação de herança múltipla

Ao lidar com herança múltipla usando classes base de modelo, surge um problema potencial em relação à resolução de função de membro ambígua. Considere o seguinte cenário:

template 
class Base {
public:
  template 
  typename std::enable_if::value>::type foo() {
    std::cout 

Aqui, a função foo() só pode ser chamada quando o parâmetro do modelo corresponde a um dos tipos no pacote Types. Agora, se uma classe derivada herda de múltiplas classes base com conjuntos de tipos não sobrepostos, o compilador pode encontrar ambiguidade ao resolver a chamada foo().

struct Derived: public Base,
                public Base
{};

Nesse caso, a chamada Derived().foo() idealmente chamaria a função de membro foo() de Base. No entanto, tanto o GCC quanto o Clang relatam uma ambigüidade.

Por que o compilador não consegue resolver a ambigüidade

O erro de compilação surge devido às regras de mesclagem para pesquisa de função de membro. De acordo com o padrão C, se a função membro não for declarada na própria classe derivada, o processo de pesquisa pesquisará as classes base por sua vez. No entanto, se os conjuntos de declarações nas classes base forem diferentes, a mesclagem se tornará ambígua.

No cenário fornecido, a classe derivada Derived não declara foo() explicitamente, portanto, o compilador deve mesclar os conjuntos de pesquisa do duas classes base. Como as classes base contêm diferentes conjuntos de declarações para foo(), a mesclagem resulta em ambigüidade.

Soluções

Para resolver essa ambigüidade, uma opção é usar declarações using na classe derivada para importar explicitamente as funções de membro desejadas. No entanto, isso exige que o usuário adicione essas declarações, o que pode ser detalhado e impraticável para listas de tipos grandes.

struct Derived: public Base,
                public Base
{
    using Base::foo;
    using Base::foo;
};

Alternativamente, pode-se usar uma classe auxiliar que coleta e mescla as funções-membro de todas as classes base, permitindo que a classe derivada as acesse diretamente.

template 
struct BaseCollector : Bases...
{
  using Bases::foo...;
};

struct Derived : BaseCollector, Base>
{};

Com essa abordagem, o usuário não precisa adicionar declarações adicionais para resolver a ambiguidade. A classe BaseCollector mescla efetivamente os conjuntos de declarações de todas as classes base, disponibilizando a função foo() para a classe derivada sem ambigüidade.

Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3