fonction surchargée appelée avec un paramètre, mais je pensais que je l'avais passé deux

StackOverflow https://stackoverflow.com/questions/2475657

Question

J'ai récemment le code refactorisé comme celui-ci (MyClass à 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;
}
  • Quelle est l'erreur,
  • pourquoi il compile (testé avec VC6 ainsi que le niveau d'alerte VC9 4 : aucune plainte) et
  • quelle est la bonne façon de le faire?

I (assumer) Je l'ai déjà toutes ces réponses, mais je pense qu'il est et problème intéressant de partager.

Mise à jour Code étendu il est « copier-coller et exécuter » able. VC9 m'a donné aucune plainte soit si VC6 est pas le problème ici. Pour être complet, la sortie est:

a:
        first: 1        second: 2       third: 1.054069532
b:
        first: 1        second: 2       third: 1.004499999
Était-ce utile?

La solution

Je ne sais pas ce que vous attendez exactement, mais nous allons commencer ...

  • Tout d'abord, VC6 fossé. Sérieusement. Son utilisation est un énorme problème, car il est tout simplement pas des normes conformes et empêche beaucoup d'options. Son utilisation est correctement comme jouer à la roulette russe.

  • Votre constructeur de m_third ne fait pas ce que vous pensez. Vous ne pouvez pas écrire une expression conditionnelle comme ceci:. « Plusieurs paramètres » n'est pas valide expression en C ++ et l'opérateur conditionnel fonctionne sur les expressions

  • Le code compile, car il est toujours correct , il ne fonctionne tout simplement pas ce que vous voulez. Au lieu d'utiliser « plusieurs paramètres », il évalue l'opérateur de point de séquence (,) qui prend juste la dernière valeur de l'expression, de sorte que votre condition est effectivement équivalent à: isUp ? y : x

  • La bonne manière est d'utiliser deux conditionals: m_third(isUp ? x : y, isUp ? y : x)

  • Le troisième constructeur de SomeMember est erroné, la valeur peut déborder, ce qui donne une valeur négative -. Je doute fortement que c'est ce que vous voulez

Autres conseils

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

Cela semble mal être. La première x est une expression inutile car elle n'a pas d'effets secondaires et le résultat ne soit pas utilisé, les deux côtés de la : ont les effets mêmes de la valeur et de côté si ?: peut être elimintated comme l'expression avant la ? n'a pas non plus d'effets secondaires .

m_third(y, x)

Mais maintenant, il ne fait pas ce que le code d'origine ne ... est-ce l'erreur?

  

Quelle est l'erreur   quelle est la bonne façon de le faire?

Je suppose que votre intention est de montrer une sorte d'utilisation naïve de l'opérateur virgule en combinaison avec ternaire?, Peut-être il y a une certaine priorité de l'opérateur intelligent et inattendu Gotcha caché, mais que je pense que le code est tout à fait artificielle. Si c'est le point, que je dirais que la « bonne façon de le faire » est de ne pas utiliser C ++ ou d'abord apprendre avant de l'utiliser. Oui, il a beaucoup de constructions qui peuvent ressembler à « bizarreries » et vous pouvez créer beaucoup de code étrangement accepté par un de regard compilateur. En utilisant C ++, je dirais que vous êtes censé connaître les outils.

  

Pourquoi ne compile

Parce qu'il ne contient pas d'erreur et il est un code C ++ correct sans ambiguïtés.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top