我无法理解此三元运算符的转换逻辑(这里是一个示例):

#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;
}

我有一个模板类singletime<T>,它是任何类型的包装器,用于案例,与该问题无关,并且具有T的转换运算符。问题是在三元运算符表达式中使用singletime<uint64_t>时。

这是有问题的行:
getvalue (flag ? singletime_64 : 0, "Ternary with singletime, > INT_MAX");

64位值将转换为int,如果该值大于INT_MAX,它将变得不正确。

该示例打印出三元运算符的某些用法类型-带有表达式的结果类型和结果值。
这是示例的输出:
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

唯一的问题是,三元运算符与singletime<uint64_t>一起使用时-它获得的值是18446744071562067968

据我了解,它试图将不同的类型转换为一种类型。

由于存在从singletime<uint64_t>uint64_t的转换运算符,它可能会使用它,但是在此之后,我不明白为什么它将两个值都转换为int而不是uint64_t了?在使用uint64_t而不是singletime<uint64_t>的示例中,将int转换为uint64_t并且不会丢失任何值

对于singletime<uint64_t>和int的情况,也没有编译器警告有关强制转换为较小的类型和潜在的数据丢失。

尝试使用gcc 4.8.2和gcc 5.2.0

最佳答案

根据标准5.16。



因此,这里0为右值,类型为int。编译器将尝试将第一个参数转换为int,并且这样做,由于您的转换运算符,可以做到。

09-11 19:25