从变量转换时出现 std::chrono::time_point 编译器错误

Nin*_*rez 5 c++ c++11 c++-chrono

我有一个类型的变量long long,表示以纳秒为单位的时间点。

我正在尝试使用 std::chrono::time_point 包装它,但编译器(VS 2017)给我带来了麻烦。

这是一个编译代码:

std::chrono::time_point<std::chrono::steady_clock> tpStart(std::chrono::nanoseconds(10ll));
std::chrono::time_point<std::chrono::steady_clock> tpEnd = std::chrono::steady_clock::now();
double d =  std::chrono::duration<double>(tpEnd - tpStart).count();
Run Code Online (Sandbox Code Playgroud)

现在,如果我10ll用变量切换值,计算持续时间的行将无法编译:

constexpr long long t = 10ll;
std::chrono::time_point<std::chrono::steady_clock> tpStart(std::chrono::nanoseconds(t));
std::chrono::time_point<std::chrono::steady_clock> tpEnd = std::chrono::steady_clock::now();
double d =  std::chrono::duration<double>(tpEnd - tpStart).count();
Run Code Online (Sandbox Code Playgroud)

这是错误代码:

错误 C2679:二进制“-”:未找到采用“重载函数”类型的右侧操作数的运算符(或没有可接受的转换)

知道为什么会这样吗?如何将 long long 类型的变量转换为 std::chrono::time_point?

Mar*_*rol 5

TLDR:这是一个最令人头疼的解析案例

prog.cc:8:59: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
std::chrono::time_point<std::chrono::steady_clock> tpStart(std::chrono::nanoseconds(t));
Run Code Online (Sandbox Code Playgroud)

修复{}而不是()

constexpr long long t = 10ll;
std::chrono::time_point<std::chrono::steady_clock> tpStart{std::chrono::nanoseconds{t}};
std::chrono::time_point<std::chrono::steady_clock> tpEnd = std::chrono::steady_clock::now();
double d =  std::chrono::duration<double>(tpEnd - tpStart).count();
Run Code Online (Sandbox Code Playgroud)

为什么它是一个最令人烦恼的解析?

std::chrono::time_point<std::chrono::steady_clock> pStart  (std::chrono::nanoseconds(t));
//                  ^^^^ Type 1 ^^^^^              ^name^      ^^^^ Type 2 ^^^^
Run Code Online (Sandbox Code Playgroud)

所以我们可以重现:

constexpr long long t = 10ll;
int fail (double (t) );
fail = 6; // compilation error here
Run Code Online (Sandbox Code Playgroud)

为什么 ?让我们去除一些噪音:

int fail (double (t) );
//  <=> 
int fail (double t);
// <=>
int fail (double) ; // Most vexing parse.
Run Code Online (Sandbox Code Playgroud)

我们可以通过切换到 {}

int Ok {double {t} };
Run Code Online (Sandbox Code Playgroud)