Ir para o conteúdo

Última atualização:2026-10-12

Vinculações estruturadas no C++17

Antes de falarmos sobre vinculações estruturadas, aqui estão algumas perguntas de entrevista: você saberia respondê-las?

  • Como usar vinculações estruturadas para acessar os membros privados de uma classe personalizada?

  • Como usar vinculações estruturadas para modificar os membros de uma classe personalizada?

Pouca gente deve saber responder essas questões, e os enunciados e respostas tampouco estão disponíveis na internet. Com base nessas perguntas, chegamos ao conteúdo deste artigo: como dar suporte a vinculações estruturadas para tipos personalizados e quais armadilhas existem nesse caminho.

Obs.: versão para quem tem pressa, as respostas e o código já estão no Planeta.

Para que o conteúdo deste artigo flua melhor, vamos partir de um exemplo.

1.Tipos personalizados

Dada a seguinte classe:

struct Foo {
  Foo(int64_t id, std::string data) : id_(id), data_(std::move(data)) {}
  void Print() { std::cout << "id = " << id_ << ", data = " << data_ << std::endl; }

 private:
  int64_t id_;
  std::string data_;
};

Para que este código funcione:

int main() {
  Foo f{12, "hello world"};
  const auto& [id, data] = f;
  std::cout << "id = " << id << ", data = " << data << std::endl;
  f.Print();
}

Se executado diretamente, a compilação falha:

 cannot decompose inaccessible member 'Foo::id_' of 'const Foo'
   42 |   const auto& [id, data] = f;

Então, o que fazer?

2.Suporte a vinculações estruturadas

Resolvemos esse problema em duas etapas:

1.Especializar std::tuple_size e std::tuple_element

namespace std {
  template <>
  struct tuple_size<Foo> : std::integral_constant<std::size_t, 2> {};

  template <>
  struct tuple_element<0, Foo> {
    using type = int64_t;
  };

  template <>
  struct tuple_element<1, Foo> {
    using type = std::string;
  };
}

2.Adicionar à estrutura acima uma função get amiga e, então, implementá-la:

template <std::size_t Index>
decltype(auto) get(const Foo& f);

template <>
decltype(auto) get<0>(const Foo& f) {
  return f.id_;
}

template <>
decltype(auto) get<1>(const Foo& f) {
  return f.data_;
}

Com isso, tudo passa a funcionar normalmente, obtendo a saída:

id = 12, data = hello world
id = 12, data = hello world

Por fim, deixo algumas perguntas:

  • Acima foi fornecido acesso somente leitura; o que acontece se modificarmos const auto & durante o acesso?

Por exemplo:

auto& [id, data] = f;
  • Como dar suporte a acesso de modificação aos membros da classe?

Ou seja, fazer esta instrução funcionar normalmente

auto& [id, data] = f;

Bem, isto encerra a seção; sintam-se à vontade para comentar na área de mensagens.

Tópicos relacionados

Comentários