Pergunta

Tenho duas classes com a seguinte estrutura:

struct A {
  A transform() const;
};

struct B {
  // returns a temporary A
  A operator*() const;
};

O * operador pode parecer um pouco estranho aqui, mas dado o contexto de seu uso é bastante natural.Na verdade, B realmente existe apenas para fornecer algum açúcar sintático para uma linguagem incorporada, portanto, seus métodos e operadores são projetados para dar a aparência desejada ao código.Dado B b, obtendo o associado A é rápido, *b.Às vezes quero ativar a transformação A imediatamente.Atualmente, isso requer alguns parênteses extras (*b).transform().Parece haver uma simplificação natural, nomeadamente b->transform().Mas operator -> é suposto retornar um ponteiro e operator * é retorna um temporário.Como posso implementar uma sobrecarga como essa?

Foi útil?

Solução

Isenção de responsabilidade:Não sou responsável por quaisquer confusões que surjam ao alterar a categoria de valor dos operadores sobrecarregados em relação aos seus equivalentes integrados.

struct just_some_type
{
    int m;

    int transform() { return m; }
};

// the intermediate helper stops the recurring application of ->
// if the lhs of -> is of a class type
struct intermediate_helper
{
    just_some_type member;

    just_some_type* operator->() { return &member; }
};

struct ptr_like
{
    just_some_type operator*()
    { return {42}; }

    intermediate_helper operator->()
    { return {{42}}; }
};

Exemplo de uso:

#include <iostream>

int main()
{
    auto p = ptr_like{};
    std::cout << (*p).transform() << "\n";
    std::cout << p->transform() << "\n";
}

Nota importante: o objeto atuado em p-> é um lvalue, como o embutido -> é aplicado a um ponteiro!Por exemplo.se você se qualificar transform com um lvalue-ref como int transform() &;, então a versão (*p).transform() não conseguirá compilar, mas p->transform() ainda é legal.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top