Je ne comprends pas cette logique de conversion de l'opérateur ternaire (voici un exemple):C++ compréhension de conversion de l'opérateur ternaire
#include <iostream>
#include <typeinfo>
#include <unistd.h>
#include <cxxabi.h>
#include <climits>
template<typename T>
struct singletime
{
private:
T value;
public:
T& operator()() {return this->value;}
operator const T&() const {return value;}
unsigned char flag_needed_for_all_types;
};
static void getvalue1 (uint64_t value, const char *call)
{
std::cout << call << ": \t" << value << std::endl << std::endl;
}
#define getvalue(x, str) \
std::cout << typeid(x).name() << std::endl; \
getvalue1(x, str);
int main (int argc, char *argv[])
{
bool flag = true;
singletime<uint64_t> singletime_64;
singletime_64() = INT_MAX+1lu;
uint64_t value_64 = singletime_64;
getvalue (flag ? singletime_64 : 0, "Ternary with singletime, > INT_MAX");
getvalue (singletime_64, "singletime w/o ternary, > INT_MAX");
getvalue (flag ? value_64 : 0, "Ternary with uint64_t, > INT_MAX");
getvalue (value_64, "uint64_t w/o ternary, > INT_MAX");
singletime_64() = INT_MAX;
uint64_t value_64_l = singletime_64;
getvalue (flag ? singletime_64 : 0, "Ternary with singletime, <= INT_MAX");
getvalue (singletime_64, "singletime w/o ternary, <= INT_MAX");
getvalue (flag ? value_64_l : 0, "Ternary with uint64_t, <= INT_MAX");
getvalue (value_64_l, "uint64_t w/o ternary, <= INT_MAX");
return 0;
}
J'ai une classe de modèle singletime<T>
, qui est un emballage de tout type, utilisé pour les cas, non lié à cette question et a un opérateur de conversion à T
. Le problème est lorsque singletime<uint64_t>
est utilisé dans une expression d'opérateur ternaire.
Ceci est la ligne problématique:
getvalue (flag ? singletime_64 : 0, "Ternary with singletime, > INT_MAX");
La valeur 64 bits est converti en int et si la valeur est au-dessus INT_MAX
, il devient incorrect.
L'exemple imprime certains types d'utilisation de l'opérateur ternaire - avec le type résultant de l'expression et la valeur résultante.
est ici la sortie de l'exemple:
int
Ternary with singletime, > INT_MAX: 18446744071562067968
singletime<unsigned long>
singletime w/o ternary, > INT_MAX: 2147483648
unsigned long
Ternary with uint64_t, > INT_MAX: 2147483648
unsigned long
uint64_t w/o ternary, > INT_MAX: 2147483648
int
Ternary with singletime, <= INT_MAX: 2147483647
singletime<unsigned long>
singletime w/o ternary, <= INT_MAX: 2147483647
unsigned long
Ternary with uint64_t, <= INT_MAX: 2147483647
unsigned long
uint64_t w/o ternary, <= INT_MAX: 2147483647
Le seul problème est lorsque l'opérateur ternaire est utilisé avec singletime<uint64_t>
- il obtient la valeur 18446744071562067968
Si je comprends bien, il essaie de convertir différents types de un type.
Comme il y a un opérateur de conversion de singletime<uint64_t>
à uint64_t
, il l'utilise peut-être, mais après je ne comprends pas pourquoi il convertit les deux valeurs en int, au lieu de uint64_t
? Dans les exemples où uint64_t
est utilisé au lieu de singletime<uint64_t>
, l'int est converti en uint64_t
et qu'aucune valeur ne perd
Dans le cas de singletime<uint64_t>
et int, il n'y a pas non plus compilateur d'avertissement au sujet de CAST pour petits caractères et la perte potentielle de données.
Essayé avec gcc 4.8.2 et gcc 5.2.0