Pergunta

Recentemente, refatorei o código como este (MyClass para MyClassR).

#include <iostream>

class SomeMember
{
public:
  double m_value;

  SomeMember() : m_value(0) {}
  SomeMember(int a) : m_value(a) {}
  SomeMember(int a, int b)
  : m_value(static_cast<double>(a) / 3.14159 +
            static_cast<double>(b) / 2.71828)
  {}
};


class MyClass
{
public:
SomeMember m_first, m_second, m_third;

MyClass(const bool isUp, const int x, const int y)
{
  if (isUp)
  {
    m_first = SomeMember(x);
    m_second = SomeMember(y);
    m_third = SomeMember(x, y);
  }
  else
  {
    m_first = SomeMember(y);
    m_second = SomeMember(x);
    m_third = SomeMember(y, x);
  }
}
};


class MyClassR
{
public:
SomeMember m_first, m_second, m_third;

MyClassR(const bool isUp, const int x, const int y)
: m_first(isUp ? x : y)
, m_second(isUp ? y : x)
, m_third(isUp ? x, y : y, x)
{
}
};


int main()
{
    MyClass a(true, 1, 2);
    MyClassR b(true, 1, 2);

    using namespace std;
    cout.precision(10);
    cout
        << "a:" << endl
        << "\tfirst: " << a.m_first.m_value 
        << "\tsecond: " << a.m_second.m_value 
        << "\tthird: " << a.m_third.m_value << endl;

    cout
        << "b:" << endl
        << "\tfirst: " << b.m_first.m_value
        << "\tsecond: " << b.m_second.m_value
        << "\tthird: " << b.m_third.m_value << endl;

    return 0;
}
  • Qual é o erro,
  • Por que isso compila (testado com vc6 bem como vc9 aviso nível 4: sem queixas) e
  • Qual é a maneira certa de fazer isso?

Eu (presumo) já tenho todas essas respostas, mas acho que é e um problema interessante de compartilhar.

Atualizar
Código estendido para que seja "copiar e colar e executar". O VC9 também não me denizou queixas VC6 não é o problema aqui.
Para completude, a saída é:

a:
        first: 1        second: 2       third: 1.054069532
b:
        first: 1        second: 2       third: 1.004499999
Foi útil?

Solução

Não tenho certeza do que exatamente você espera, mas vamos começar ...

  • Primeiro, Ditch VC6. Seriamente. Usá -lo é um grande problema, pois não são padrões em conformidade e impede muitas opções. Usá -lo corretamente é como interpretar a roleta russa.

  • Seu construtor de m_third Não faz o que você acha que faz. Você não pode escrever uma expressão condicional como esta: "Vários parâmetros" não é um válido expressão em C ++, e o operador condicional trabalha em expressões.

  • O código compila porque ainda é correto, simplesmente não faz o que você deseja. Em vez de usar "vários parâmetros", ele avalia o operador de ponto de sequência (,) que apenas leva o último Valor da expressão, portanto, seu condicional é efetivamente equivalente a: isUp ? y : x

  • O caminho certo é usar dois condicionais: m_third(isUp ? x : y, isUp ? y : x)

  • O terceiro construtor de SomeMember está errado, o valor pode transbordar, produzindo um valor negativo - duvido muito que seja isso que você deseja.

Outras dicas

m_third(isUp ? x, y : y, x)

Isso parece errado estar. O primeiro x é uma expressão inútil, pois não tem efeitos colaterais e o resultado não é usado, então os dois lados do : tem o mesmo valor e efeitos colaterais, então ?: pode ser eliminado como a expressão antes do ? Também não tem efeitos colaterais.

m_third(y, x)

Mas agora não faz o que o código original faz ... é o erro?

Qual é o erro Qual é a maneira certa de fazer isso?

Eu acho que sua intenção é mostrar algum tipo de uso ingênuo do operador de vírgula em combinação com o ternário?, Talvez exista uma prioridade do operador inteligente e inesperada, Gotcha Hidden, mas acho que o código é absolutamente artificial. Se esse é o ponto, eu diria que a "maneira correta de fazê -lo" é não usar C ++ ou primeiro aprenda antes de usá -lo. Sim, ele tem muitas construções que podem parecer "peculiaridades" e você pode criar muito código estranhamente aceito por um compilador. Ao usar C ++, eu diria que você se supõe que conheça as ferramentas.

Por que é compilar

Porque não contém erro e é um código C ++ correto sem ambiguidades.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top