Estou lendo aqui e ali sobre vinculações de estrutura em C++20 especificamente. Esse recurso foi, no entanto, introduzido em C++17 e teve poucos problemas:
- Não é possível usar especificadores de armazenamento (
static
outhread_local
) - Quando usado dentro de uma classe, se os membros de dados forem,
private
as ligações de estrutura usadas em métodos ou funções amigas não devem funcionar.
Para testar isso, escrevi este código:
#include <string>
struct Point {
int x, y;
};
class AClass {
private:
std::string mString;
int mId;
public:
void aMethod(const AClass& p) {
auto s = p.mString;
auto [str, id] = p; // this should not work, because we're
// accessing private memebers
}
friend void aFriendFunction(const AClass& p) {
auto s = p.mString;
auto [str, id] = p; // Likewise as aMethod
}
};
int main() {
Point p{3, 5};
// This shouldn't work in C++17
static auto [u, v] = p; // This gives a warning, compilation depends
return 0;
}
O que, pelo que entendi, não deveria funcionar . E presumi que por "não funcionar" não deveria compilar. No entanto, esta linha:
g++ main.cpp -o out -std=c++17
Me dá uma saída que parece válida e sem problemas. Então por que isso está funcionando? Estou esquecendo de algo?
Também estou notando que no gcc 7.1. isso realmente dá o erro esperado (usando um compilador online). Mas ao mudar para minha versão do gcc (13.3.0) recebo o aviso mencionado anteriormente. Isso levanta para mim a questão de como a vinculação estruturada mudou dentro da mesma versão C++.
Embora o padrão C++ seja publicado novamente a cada três anos desde 2011, é possível para o comitê identificar defeitos de linguagem e aplicar correções retroativamente a revisões de padrões já publicadas (até mesmo o C++14 viu atualizações anos depois). Isso não afetará compiladores antigos, mas conforme os compiladores forem atualizados, eles podem implementar as correções e você verá mudanças de comportamento mesmo para a mesma troca de padrão C++.
A página cppreference para ligações estruturadas lista os problemas que você explorou em sua postagem e links para os problemas/propostas do CWG para corrigi-los. Especificamente
public
, para serem acessíveis no ponto da declaração de ligação estruturada.Ambos os artigos foram aplicados retroativamente como Relatórios de Defeitos no C++17 (se a cppreference for confiável). É por isso que o GCC 13.3.0 está aceitando o "código problemático", mas o GCC 7.1 não. Os defeitos não foram abordados e ratificados na época do lançamento do GCC 7.1 (2017, e o rastro de papel é de 2018).