据我所知,std::to_integer<T>
等效于T(value)
,其中value
是类型为std::byte
的变量。
我研究了主要编译器的一些实现,发现在这种情况下 equivalent 的意思是实现为。换句话说,大多数情况下,to_integer
实际上被实现为:
return T(value);
仅此而已。
我不明白什么是该功能的目的?
具有讽刺意味的是,弊大于利。我应该为这样的函数包括一个完整的标头,以避免出现类似C的强制转换,无论如何都直接内联。
还有其他原因吗?或者它真的是类似C的强制转换的好看替代品?
答案 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;
}