"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 o SFINAE não funciona com funções de membros de modelos de classe?

Por que o SFINAE não funciona com funções de membros de modelos de classe?

Publicado em 2024-11-10
Navegar:392

Why Doesn't SFINAE Work with Member Functions of Class Templates?

Por que SFINAE (enable_if) não funciona para funções de membro de um modelo de classe?

Em C , SFINAE (Falha de substituição não é um erro) permite que você ativar ou desativar o código dependendo do tipo de argumento do modelo. No entanto, ao lidar com funções de membro de um modelo de classe, SFINAE muitas vezes não funciona como esperado.

Aqui está um exemplo que demonstra o problema:

#include 

struct A {};
struct B {};

template 
struct Foo
{
    typename std::enable_if<:is_same a>::value>::type bar()
    {}

    typename std::enable_if<:is_same b>::value>::type bar()
    {}
};

Neste exemplo, Foo define duas funções de membro sobrecarregadas bar(). A primeira sobrecarga é habilitada quando T é A, e a segunda é habilitada quando T é B. No entanto, se você tentar compilar este código, receberá uma mensagem de erro indicando que as sobrecargas não podem ser resolvidas.

A razão para este erro é que SFINAE só funciona para argumentos de modelo deduzidos. No caso de funções-membro de um modelo de classe, o argumento do modelo não é deduzido, mas especificado explicitamente. Para corrigir o problema, você pode usar uma das seguintes técnicas:

  • Use argumentos de modelo explícitos:

    struct Foo
    {
      void bar(A) {}
      void bar(B) {}
    };
  • Use std::enable_if dentro das funções de membro:

    template 
    struct Foo
    {
      template
      typename std::enable_if<:is_same a>::value>::type bar() {}
    
      template
      typename std::enable_if<:is_same b>::value>::type bar() {}
    };
  • Usar especialização explícita de modelo de classe:

    template  struct Foo { void bar() {} };
    template  struct Foo { void bar() {} };
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