std :: to_integer的目的是什么?

时间:2019-06-22 22:10:31

标签: c++ c++17 c++-standard-library

据我所知,std::to_integer<T>等效于T(value),其中value是类型为std::byte的变量。
我研究了主要编译器的一些实现,发现在这种情况下 equivalent 的意思是实现为。换句话说,大多数情况下,to_integer实际上被实现为:

return T(value);

仅此而已。

我不明白什么是该功能的目的?
具有讽刺意味的是,弊大于利。我应该为这样的函数包括一个完整的标头,以避免出现类似C的强制转换,无论如何都直接内联。

还有其他原因吗?或者它真的是类似C的强制转换的好看替代品?

4 个答案:

答案 0 :(得分:11)

  

对于像C的强制转换来说,这真的是一个不错的选择,仅此而已?

您说的好像是一些琐碎的细节。

广播很危险。将某些内容强制转换为错误的类型很容易,并且编译器通常不会阻止您执行此操作。此外,由于const url = 'upload.php' const request = new Request(url, { method: 'POST', body: formData }); fetch(request) 在C ++中不是整数类型,因此使用数字字节值通常需要大量的转换。拥有可明确转换为整数的函数可提供更安全的用户体验。

例如,std::byte是完全合法的,而float(some_byte)被明确禁止。 to_integer<float>(some_byte)要求to_integer<T>是整数类型。

T更安全的替代方案。

  

我应该为该功能包括一个完整的标题

如果用“整个标头”表示您是从to_integer那里获得的相同标头,因此按定义已经包含...

答案 1 :(得分:9)

std::to_integer<T>(some_byte)等效于// Task for installing frontend dependencies in web task installDependencies(type: NpmTask) { args = ['install'] execOverrides { it.workingDir = '../web' } } // Task for executing build:gradle in web task buildWeb(type: NpmTask) { args = ['run', 'build:gradle'] execOverrides { it.workingDir = '../web' } } // Before buildWeb can run, installDependencies must run buildWeb.dependsOn installDependencies // Before build can run, buildWeb must run build.dependsOn buildWeb ,如果它确实可以编译T(some_byte)等效于T(some_byte)的不安全C样式强制类型转换,可以强制转换do scary things。另一方面,(T)some_byte被适当地限制为仅在安全的情况下起作用:

  

仅当std::to_integer为true时,此重载才参与重载解析。

如果std::is_integral_v<IntegerType>实际上不是整数类型,而不是可能具有未定义的行为,则代码将无法编译。如果T实际上不是some_byte,而不是可能具有未定义的行为,则代码将无法编译。

答案 2 :(得分:3)

除了已经提到的意图和安全性问题表达之外,我从委员会在纸上的讨论中得到的想法是,它像std::to_string一样,将来可能会有更多的超载。

答案 3 :(得分:2)

C样式强制转换与std::to_integer<T>不同。请参见以下示例。

std::to_integer<T>仅在std::is_integral_v<T>为true时才参与重载解析。

#include <cstddef>
#include <iostream>

template <typename T>
auto only_return_int_type_foo(std::byte& b)
{
    return std::to_integer<T>(b);
}

template <typename T>
auto only_return_int_type_bar(std::byte& b)
{
    return T(b);
}

int main()
{
    std::byte test{64};
    // compiles
    std::cout << only_return_int_type_foo<int>(test) << std::endl;

    // compiler error
    std::cout << only_return_int_type_foo<float>(test) << std::endl;

    // compiles
    std::cout << only_return_int_type_bar<int>(test) << std::endl;

    // compiles
    std::cout << only_return_int_type_bar<float>(test) << std::endl;
}