Различные результаты между целочисленной переменной и приведением целого числа к целому - PullRequest
1 голос
/ 02 апреля 2020

Я написал обобщенный класс таймера c, который использует время std::chrono для таймера. Это пример кода, который показывает проблему:

#include <iostream>
#include <chrono>

template <typename Rep, typename TimeType>
class Timer {
  public:
    Timer(const std::chrono::duration<Rep, TimeType> timerLength);
    ~Timer() = default;
  private:
    std::chrono::duration<Rep, TimeType> _timerLength;
};

template <typename Rep, typename TimeType>
Timer<Rep, TimeType>::Timer(const std::chrono::duration<Rep, TimeType> timerLength) : _timerLength{timerLength} {}

int main()
{
    constexpr int time_ms = 1000;

    Timer timer(std::chrono::milliseconds(time_ms));

    return 0;
}

Этот код приводит к ошибке: error: deduced class type ‘Timer’ in function return type.

Эту ошибку можно устранить, поместив фактическое значение int непосредственно в таймер. в основном:

Timer timer(std::chrono::milliseconds(1000));

Кроме того, эту ошибку можно устранить, приведя параметр time_ms к целому числу:

Timer timer(std::chrono::milliseconds(`static_cast<int>(time_ms)));

Я ожидал того же результата от целочисленной переменной и приведения целое число - целое число.

Эту ошибку нельзя устранить, удалив constexpr переменной time_ms.

Мой вопрос: в чем различия между целочисленной переменной и приведением целое число в целое число (а также вставка числа непосредственно в std::chrono::milliseconds())? И почему это имеет значение в первую очередь?

1 Ответ

2 голосов
/ 02 апреля 2020

Вы жертва неприятного разбора. С -Wall clang даже предупредит об этом

source>:24:16: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]

    Timer timer(std::chrono::milliseconds(time_ms));

               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

и предложит исправить это.

<source>:24:17: note: add a pair of parentheses to declare a variable

    Timer timer(std::chrono::milliseconds(time_ms));

                ^

                (                                 )

Но вы можете устранить неоднозначность и другими способами.

Timer timer{std::chrono::milliseconds(time_ms)};
Timer timer(std::chrono::milliseconds{time_ms});
auto timer = Timer(std::chrono::milliseconds(time_ms));
Timer timer(static_cast<std::chrono::milliseconds>(time_ms));

, а также вставку литерала int в выражение или явное приведение к int, как вы сами заметили.

...