c ++ usando declaração, escopo e controle de acesso

Normalmente, a declaração 'using' é usada para trazer para o escopo algumas funções de membros das classes base que, de outra forma, estariam ocultas. Desse ponto de vista, é apenas um mecanismo para tornar as informações acessíveis mais convenientes de usar.
No entanto: a declaração 'using' também pode ser usada para alterar restrições de acesso (não apenas para funções, mas também para atributos). Por exemplo:

class C{
public:
  int a;
  void g(){ cout << "C:g()\n"; }
  C() : a(0){}
};

class D : public C{
private:
  using C::a;
  using C::g;
public:
  D() { a = 1; }
};

int main(void){
  D d;
  cout << d.a << endl;  //error: a is inaccessible
  C *cp = &d;
  cout << cp->a << endl; //works
  d.g();  //error: g is inaccessible
  cp->g();  //works
  return 0;
}

Eu acho que essa limitação de acesso na classe derivada é realmente inútil, porque você sempre pode acessar g () e a de um ponteiro para a classe base. Portanto, não deveria haver pelo menos algum tipo de aviso do compilador? Ou não seria ainda melhor proibir essa limitação de acesso por uma classe derivada? A declaração de uso não é a única possibilidade de adicionar restrições ao acesso. Isso também pode ser feito substituindo a função de uma classe base e colocando-a em uma seção com mais restrições de acesso. Existem alguns exemplos razoáveis em que é realmente necessário limitar o acesso dessa maneira? Caso contrário, não vejo por que deveria ser permitido.

E outra coisa: pelo menos com g ++, o mesmo código compila bem sem a palavra 'using'. Isso significa o exemplo acima: é possível escrever C :: a; e C :: g; em vez de usar C :: a; usando C :: g; O primeiro é apenas um atalho para o último ou há algumas diferenças sutis?

//EDITAR:
Assim, a partir da discussão e respostas abaixo, minha conclusão seria:
- é permitido limitar restrições de acesso em classes derivadas com herança pública
- existem exemplos úteis em que poderia ser usado
- seu uso pode causar problemas em combinação com modelos (por exemplo, uma classe derivada não pode mais ser um parâmetro válido para alguma classe / função de modelo, embora seja a base)
- um design de linguagem mais limpo não deve permitir tal uso
- o compilador pode pelo menos emitir algum tipo de aviso

questionAnswers(3)

yourAnswerToTheQuestion