函数参数不是左值?

时间:2014-06-19 00:07:59

标签: c++ lvalue

我创建的功能可在几秒钟内获得const int时间,并以小时分和秒为单位打印实时。
localtime可以做到这一点,从tm返回time.h结构。我要做的就是:

bool elapsed(const int timeout) {
    //Cast the integer to time_t
    struct tm * now = localtime( (time_t&) &timeout);

    std::wcout<<L"Time elapsed: "<<now->tm_hour<<':'<<now->tm_min<<':'<<now->tm_sec<<"\r\n";
    return timeout>600;
}

但这会引发错误:(time_t&) & timeout - 表达式必须是左值

除了在辅音之前用an困扰我之外,这个错误对我来说毫无意义。我读过lvalues are things with names。这种情况是个例外吗?

3 个答案:

答案 0 :(得分:4)

localtime函数需要一个time_t*类型的参数,一个指向time_t对象的指针。

在当前代码中,您没有time_t对象,因此无法创建指向此类对象的有效指针。

定义一个本地time_t对象,初始化为(转换)值timeout,并将该对象的地址传递给localtime

bool elapsed(const int timeout) {
    time_t t_timeout = timeout;
    struct tm * now = localtime(&t_timeout);
    // ...

但如果可能的话,首先将timeout参数声明为time_t会更清晰:

bool elapsed(time_t timeout) {
    struct tm * now = localtime(&timeout);
    // ...

这一切都假定您的timeout值是传递给localtime()的合理值。很可能不是。 time_t值表示时间,而不是持续时间;在很多系统上,这是自格林威治标准时间1970-01-01 00:00:00以来的秒数。例如,timeout值为3600表示1970年1月1日凌晨1点。localtime顾名思义,将其视为当地时间,因此根据您的时区而定例如,12月31日下午4点。这都是对time_t值的最常见解释;语言标准只保证它是一种算术类型,能够代表以某种方式

如果您的目标是将timeout值分解为小时,分钟和秒,请自行执行算法:

int seconds = timeout % 60;
int minutes = timeout / 60; // integer division truncates
int hours = minutes / 60;
minutes %= 60;

至于为何您收到该特定错误消息:引用必须引用对象。当我使用g ++编译你的代码时,我得到:

c.cpp:6:45: error: invalid cast of an rvalue expression of type
            'const int*' to type 'time_t& {aka long int&}'

左值大致是一个引用对象的表达式。给定

int x = 42;

表达式x是一个值,但42x+1不是。

表达式timeout是左值,因为它是对象的名称。表达式&timeout 不是左值。它计算为值{timeout的地址,类型为time_t*),但不引用对象,因为您没有类型为time_t*的对象参考。

您可以将左值转换(强制转换)为引用类型。由于&timeout不是左值,因此演员表无效。

但这并不重要,因为转换为引用在这种情况下没有意义。告诉你如何正确地进行演员表是没有用的,因为不需要演员表或者你想要完成的演出。你需要的只是一个简单的算术 - 没有指针,没有引用,没有演员表。

答案 1 :(得分:1)

Lvalues确实是“有名字的东西”(通常,即使这不是一个确切的规则)。但在你的情况下,有问题的“事物”是&timeout。此表达式求值为timeout变量的地址。此地址没有名称。地址只是一个临时中间值。这显然不是左值。

编译器请求左值的原因是您对引用类型(time_t &)的强制转换。只有左值可以用作这种演员的操作数。这必须是您的错字,因为localtime期望指针time_t作为参数,而不是参考。您的广告素材显然应该看起来像(time_t *)(或更好,(const time_t *)),但您错误地输入&来代替*

当然,重新解释 int左值作为time_t左值的做法(这是你对你的&所做的 - 并且演员组合)是值得怀疑的。如果你知道你的time_t是一个整数类型并且想要依赖它,那么转换比重新解释更有意义

time_t tt_timeout = timeout;
struct tm * now = localtime(&tt_timeout);

答案 2 :(得分:0)

(time_t&)替换为(time_t*)

这将解决构建错误。最有可能导致运行时错误。