为什么 decltype 和 is_same 的组合会产生错误的结果?

Why the combination of decltype and is_same gives wrong result?

提问人:CPW 提问时间:10/27/2023 最后编辑:HolyBlackCatCPW 更新时间:10/28/2023 访问量:52

问:

我有以下功能:

template<typename T> auto print_type_info(const T& t) {  // C++17
    if constexpr (std::is_same<T, int>::value) {
        return t + 1;    // int case
    } else if constexpr (std::is_same<decltype(t), double&>::value) {
        return t + 0.1;    // double case
    } else {
        return t;    // other case
    }
}
void main() {
    assert(print_type_info(1) == 2);      // int test
    assert(print_type_info(0.1) == 0.2);  // double test
    assert(print_type_info("0") == "0");  // char* test
}

在 VSCode 中运行上述断言测试:

  • int 测试正确地进入 int 大小写。
  • 双重测试在运行时错误地进入另一种情况。
  • char* 大小写在编译时大小写中错误地进入双大小写。

我对双重情况进行了以下更改,所有更改的结果都相同:

  • 双倍&
  • 多布勒
  • 常量双人间
  • 常量双&

为什么会这样?

C++ C++11 模板 decltype

评论

3赞 HolyBlackCat 10/27/2023
正确的类型是 。你是如何确定“进入......运行时/编译时的大小写“?在比较这样的指针时,也不会给你正确的结果,使用 或 .const double &==strcmpstring_view
4赞 molbdnilo 10/27/2023
当心浮点运算 – 不一定等于 .0.1 + 0.10.2
0赞 Marek R 10/27/2023
godbolt.org/z/jxnTMP3qT
0赞 molbdnilo 10/27/2023
是什么让您认为任何条件都会在运行时得到评估?
0赞 Marek R 10/27/2023
重点是显示所涉及的类型。在运行时打印这些类型名称比在编译时打印更容易。通常,建议创建一致性测试,并在编译时(以证明它们在编译期间有效)和运行时进行评估,以便于调试。

答:

0赞 CPW 10/28/2023 #1

正如 HolyBlackCat 所指出的,正确答案是:

template<typename T> auto print_type_info(const T& t) {  // C++17
    if constexpr (std::is_same<T, int>::value) {
        return t + 1;
    } else if constexpr (std::is_same<decltype(t), const double&>::value) {
        return t + 0.1;
    } else {
        return t;
    }
}