Substituir '::' por '. criar ambiguidades em C ++?


95

No C ++, o operador ::é usado para acessar classes, funções e variáveis ​​em um espaço para nome ou classe.

Se a especificação de linguagem usada em .vez de ::nesses casos também gostar ao acessar variáveis ​​/ métodos de instância de um objeto, isso causaria possíveis ambiguidades que não estão presentes ::?

Dado que o C ++ não permite nomes de variáveis ​​que também são um nome de tipo, não consigo pensar em um caso em que isso poderia acontecer.

Esclarecimento: Não estou perguntando por que ::foi escolhido ., apenas se poderia ter funcionado também?


Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
— Samuel Liew

Respostas:


124

Devido a tentativas de tornar o C ++ principalmente compatível com o código C existente (que permite colisões de nomes entre nomes de objetos e tags struct), o C ++ permite colisões de nomes entre nomes de classes e nomes de objetos.

O que significa que:

struct data {
    static int member;
};

struct data2 {
    int member;
};

void f(data2& data) {
    data.member = data::member;
}

é um código legítimo.


11
Portanto, a resposta para a pergunta no título é Sim, seria , não é?
— Enrico Maria De Angelis

2
@EnricoMariaDeAngelis não é assim tão simples. Se o C ++ fosse desenvolvido como uma linguagem completamente nova, como Java ou C #, a ambiguidade provavelmente poderia ser evitada . Mas o C ++ foi desenvolvido como "C com classes", e é por isso que não é. "Sim, será " é uma resposta correta, mas para uma pergunta diferente.
— Kit.

Espere, não é a linha de atribuição apenas mostrando que colocar .ou ::entre os mesmos dois "palavras" tem efeito diferente ( data.memberrefere-se à memberdo dataobjeto da classe data2, ao passo que data::memberse refere ao memberda classe data)?
— Enrico Maria De Angelis

11
Sim, mas não é algo que os designers de idiomas devam se orgulhar. É apenas um artefato de decisões de compatibilidade.
— Kit.

Ok, eu entendo que a forma como o C ++ é hoje e tem sido até agora (também) depende do que C era no momento em que o C ++ se desenvolveu a partir dele. Mas falando do C ++ como é e deixando de lado por que é como é, haveria uma ambiguidade se todos ::fossem alterados para .. De certa forma, você já respondeu sim . Simplesmente não posso violar seu primeiro comentário. Talvez meu nível faça esse comentário parecer esfumaçado para mim.
— Enrico Maria De Angelis

37

Um exemplo em que ambos são válidos, mas referem-se a objetos diferentes:

#include <iostream>

struct A {
    int i;
};

struct B {
    int i;
    A B;
};

int main() {
    B x {0, 1};
    std::cout << x.B.i << '\n';
    std::cout << x.B::i << '\n';
}

Veja ao vivo em coliru .


E este não poderia ser facilmente resolvido com diferentes decisões de design!
— user253751 3/02

7

Há diferença entre a::be a.bonde ::implica quea usado como espaço para nome, o que significa que é espaço para nome ou nome do tipo. Desde que o C ++ ofereça suporte a herança plural não virtual e que uma variável possa ter o mesmo nome que um tipo, isso reduz as chances de fazer referência a objetos incorretos. É necessário para a metaprogramação de modelos.

Outro exemplo seria &B::foovs &B.foono contexto da classe B.


2

Vamos estender o exemplo do @Deduplicator:

#include <iostream>

struct A {
    int i;
};

struct B : public A {
    int i;
    A A;
};

int main() {
    B x {1, 2};
    std::cout << x.i << '\n';
    std::cout << x.B::i << '\n';  // The same as the line above.
    std::cout << x.A.i << '\n';
    std::cout << x.A::i << '\n';  // Not the same as the line above.
}

Ao vivo no Coliru Viewer

Não tendo a possibilidade de diferenciar com a ajuda de ::, qual membro queremos acessar, é impossível acessar membros declarados em uma classe pai com nomes idênticos.


A A(nome da variável que também é um nome de tipo) não é válido em C ++, portanto, este exemplo não funciona por enquanto
— Jimmy RT

11
@ JimmyR.T. Há o exemplo da vida profissional no Coliru Viewer. Confirme sua declaração com um parágrafo da norma.
— SM

se alguém adicionasse o diamante de herança amaldiçoada aqui com a mesma coisa do outro lado, seria um pináculo de nomear a esquizofrenia possível em C ++
— Swift - sexta-feira
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.