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.