no viable conversion from 'int' to 'Time'

﹥>﹥吖頭↗ 提交于 2019-12-25 19:09:10

问题


I am having an error in a user defined + operator:

#include <iostream>

using namespace std;

class Time{
    int h;
    int m;
    int s;

public:
    Time();    
    Time(int x,int y, int z) {
        h=x;
        m=y;
        s=z;
    } 

    operator int() {
        return(h*3600 + m*60 + s);    
    } 

    void display() { 
        cout<<h<<endl;
        cout<<m<<endl;
        cout<<s<<endl;
    }
};      

int main(){
    Time t1(2, 3, 4);
    Time t2 = 200 + (int)t1;

    t2.display();  
}

note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const Time &' for 1st argument

How can I fix this?


回答1:


You can fix your problem by changing your operator+ to

Time operator+(int total){
    total=total+h*3600+m*60+s;
    Time temp;
    temp.h = total / 3600;
    temp.m = (total % 3600) / 60;
    temp.s = total % 60;

    return temp;
}

First the total number of seconds is calculated as in your example. Then a temporary Time is created. Since it can't be created from one int, its properties are set one by one.




回答2:


As written, the line where t2 is assigned a value assumes a couple things that are currently missing:

  1. an int and a Time instance can be added (by operator+);
  2. there's an implicit conversion from int to the Time class.

Neither of these are defined by the code as presently written.

Solution: This may be more thorough than you might need, but it does illustrate subtleties of operator overloading and the work needed to consider different possible ways a class might be used.

An Important assumption I made: The way the calculation of Time::operator int() is currently written implies that the int value should be interpreted as the number of seconds. These type of assumptions should be clearly, and explicitly documented in a comment.

Write the member operator+=(int) to define how an int is interpreted as a Time value.

Time& Time::operator+=(int secs)
{
    // Account for overflow (s >= 60 and m >= 60).
    int totalSecs = (h*3600) + (m*60) + s + secs;
    // Breakdown new total into hours, minutes, and seconds.
    h = totalSecs / 3600;
    m = (totalSecs - (h*3600)) / 60;
    s = totalSecs - (h*3600) - (m*60);
    return *this;
}

Now write the two non-member friend functions to implement binary operators in terms of Time::operator+=(). This covers either operand order (int + Time) or (Time + int):

friend Time operator+(const Time& t, int secs)
{
    Time sum(t);
    return sum += secs;
}
friend Time operator+(int secs, const Time& t)
{
    Time sum(t);
    return sum += secs;
}

Optional: You may also write another ctor to define the inverse conversion from int to Time in terms of Time::operator+=() too:

explicit Time::Time(int secs)
{
    // Initialize members to zero.
    h = m = s = 0;
    // Add specified seconds.
    *this += secs;
}

Optional: Even with all this above, you still haven't yet defined a binary operator+() between two Time instances. This will do the trick:

friend Time operator+(const Time& tleft, const Time& tright)
{
    Time sum(tleft);
    return sum += static_cast<int>(tright);
}

Note that the calculation logic of considering overflow from seconds to minutes and minutes to hours is encapsulated in a single location operator+=(int).

One last point: The Time::operator int() conversion should be declared as a 'const' member function because it doesn't alter its member values. This is required in order for the above operator+(Time,Time) function to compile since the conversion is used in the static_cast<> expression.

// Conversion from Time to int as total seconds.
operator int() const
{
    return (h*3600 + m*60 + s);
} 


来源:https://stackoverflow.com/questions/51595551/no-viable-conversion-from-int-to-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!