Esta é a melhor maneira de fazer uma declaração "com" em C ++?
-
27-09-2019 - |
Pergunta
Editar:
Portanto, essa pergunta foi mal interpretada em um grau tão ridículo que não tem mais sentido. Não sei Como as, desde a pergunta que eu realmente Perguntou era se minha implementação específica disso - sim, conhecido por ser inútil, sim, não remotamente parecido com C ++ idiomático - a macro era tão boa quanto poderia ser, e se necessariamente teve que usar auto
, ou se houve uma solução alternativa adequada. Não deveria gerar tanta atenção, e certamente não é um mal -entendido dessa magnitude. É inútil pedir aos entrevistados que editem suas respostas, não quero que ninguém perca a reputação por causa disso, e há algumas boas informações flutuando por aqui para possíveis futuros espectadores, então vou escolher arbitrariamente um dos votos inferiores Respostas para distribuir uniformemente a reputação envolvida. Avance, nada para ver aqui.
Eu vi essa questão e decidi que poderia ser divertido escrever um with
Declaração em C ++. o auto
A palavra -chave torna isso realmente fácil, mas existe uma maneira melhor de fazê -lo, talvez sem usar auto
? Eu me eliminei certos bits do código para a brevidade.
template<class T>
struct with_helper {
with_helper(T& v) : value(v), alive(true) {}
T* operator->() { return &value; }
T& operator*() { return value; }
T& value;
bool alive;
};
template<class T> struct with_helper<const T> { ... };
template<class T> with_helper<T> make_with_helper(T& value) { ... }
template<class T> with_helper<const T> make_with_helper(const T& value) { ... }
#define with(value) \
for (auto o = make_with_helper(value); o.alive; o.alive = false)
Aqui está um exemplo de uso (atualizado) com um caso mais típico que mostra o uso de with
como é encontrado em outros idiomas.
int main(int argc, char** argv) {
Object object;
with (object) {
o->member = 0;
o->method(1);
o->method(2);
o->method(3);
}
with (object.get_property("foo").perform_task(1, 2, 3).result()) {
std::cout
<< (*o)[0] << '\n'
<< (*o)[1] << '\n'
<< (*o)[2] << '\n';
}
return 0;
}
Eu escolhi o
Porque é um identificador incomum, e sua forma dá a impressão de uma "coisa genérica". Se você tem uma ideia para um identificador melhor ou uma sintaxe mais utilizável, por favor, sugira.
Solução
? Tentativa de sintaxe VB em C ++
with
Diz fazer todas as coisas no bloco a seguir por padrão, referenciando o objeto que eu disse para fazer isso certo? Executa uma série de declarações fazendo referência repetida a um único objeto ou estrutura.
with(a)
.do
.domore
.doitall
Então, como o exemplo está dando a mesma sintaxe?
Para mim, exemplos de por que usar um onde vários de referência
Então, em vez de
book.sheet.table.col(a).row(2).setColour
book.sheet.table.col(a).row(2).setFont
book.sheet.table.col(a).row(2).setText
book.sheet.table.col(a).row(2).setBorder
Você tem
with( book.sheet.table.col(a).row(2) )
.setColour
.setFont
.setText
.setBorder
parece tão fácil e mais comum sintaxe em c ++ a
cell& c = book.sheet.table.col(a).row(2);
c.setColour
c.setFont
c.setText
c.setBorder
Outras dicas
Se você usar auto
, por que usar macros?
int main()
{
std::vector<int> vector_with_uncommonly_long_identifier;
{
auto& o = vector_with_uncommonly_long_identifier;
o.push_back(1);
o.push_back(2);
o.push_back(3);
}
const std::vector<int> constant_duplicate_of_vector_with_uncommonly_long_identifier
(vector_with_uncommonly_long_identifier);
{
const auto& o = constant_duplicate_of_vector_with_uncommonly_long_identifier;
std::cout
<< o[0] << '\n'
<< o[1] << '\n'
<< o[2] << '\n';
}
{
auto o = constant_duplicate_of_vector_with_uncommonly_long_identifier.size();
std::cout << o <<'\n';
}
}
Edit: sem auto
, Apenas use typedef
e referências.
int main()
{
typedef std::vector<int> Vec;
Vec vector_with_uncommonly_long_identifier;
{
Vec& o = vector_with_uncommonly_long_identifier;
o.push_back(1);
o.push_back(2);
o.push_back(3);
}
}
Para C ++ 0x (que você está assumindo):
int main() {
std::vector<int> vector_with_uncommonly_long_identifier;
{
auto& o = vector_with_uncommonly_long_identifier;
o.push_back(1);
o.push_back(2);
o.push_back(3);
}
}
Por que não usar apenas um bom lambda?
auto func = [&](std::vector<int>& o) {
};
func(vector_with_a_truly_ridiculously_long_identifier);
O fato simples é que, se seus identificadores forem tão longos, você não pode digitá -los sempre, use uma referência, função, ponteiro, etc. para resolver esse problema ou, melhor, refatorar o nome. Declarações como esta (por exemplo, usando () em C#) têm efeitos colaterais adicionais (limpeza determinística, no meu exemplo). Sua declaração no C ++ não tem benefícios reais notáveis, pois na verdade não invoca nenhum comportamento adicional contra apenas escrever o código.