【发布时间】:2017-02-16 14:10:14
【问题描述】:
我看不懂这个三元运算符的转换逻辑(这里是一个例子):
#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
【问题讨论】: