std::common_type的用途是什么
What is the purpose of std::common_type?
我开始研究std::common_type
,但并不完全确定它的用途和功能。有几件事仍然让我觉得奇怪:
- 参数的顺序很重要:
common_type<Foo, Bar, Baz>
可能与common_type<Baz, Foo, Bar>
不同。其中一个可能编译,另一个可能不编译。虽然从common_type
的定义方式中可以清楚地看到这一点,但它感觉很奇怪,也不直观。这是因为缺乏普遍的解决方案还是有意的 - 实例化可能会导致编译器错误,而不是我可以处理的问题。如何检查
common_type
是否真的会编译?is_convertible
还不够,因为common_type
可能是专门化的 -
在这种情况下,仍然没有办法找出常见的类型:
struct Baz; struct Bar { int m; }; struct Foo { int m; }; struct Baz { Baz(const Bar&); Baz(const Foo&); };
建议的解决方案是专门化
common_type
,这很乏味。有更好的解决方案吗?
参考参见N3242中的§20.9.7.6表57。
std::common_type
是为与std::duration
一起使用而引入的--如果添加std::duration<int>
和std::duration<short>
,则结果应该是std::duration<int>
。与其指定源源不断的允许配对,不如决定委托给一个单独的模板,该模板使用适用于?:
算术if运算符的核心语言规则来找到结果。
然后,人们发现这个模板通常是有用的,它被添加为std::common_type
,并被扩展为处理任意数量的类型。在C++0x库中,它只用于类型对。
您应该能够使用新的SFINAE规则来检测std::common_type
的某些实例化是否有效。不过我还没试过。在大多数情况下,如果没有"公共类型",那么无论如何都没有任何有意义的事情可以做,所以编译错误是合理的。
std::common_type
不是魔法——它遵循?:
的规则。如果true?a:b
将进行编译,std::common_type<decltype(a),decltype(b)>::type
将为您提供结果的类型。
以下是std::common_type
:的一些用例
1.方差包的和
以下是需要common_type
:的变差和版本
template<typename... T>
constexpr auto sum(T&&... values) {
std::common_type_t<T...> sum {}; // <= here we need std::common_type
// see code in the link above for the machinery of the below code
static_for<sizeof...(T)>([&](auto index) {
sum += get<index>(values...);
});
return sum;
}
上面的例子是使用这个和这个SO职位的机器。
注意:您可以在不需要common_type
:的情况下使用以下代码实现相同的功能
template<typename T>
auto sum(T&& t) {
return t;
}
template<typename T, typename... Ts>
auto sum(T&& t, Ts&&... ts) {
return t + sum(std::forward<Ts>(ts)...);
}
2.要求可变包具有通用类型
以下代码基于此SO帖子。
template <typename AlwaysVoid, typename... Ts>
struct has_common_type_impl : std::false_type {};
template <typename... Ts>
struct has_common_type_impl<std::void_t<std::common_type_t<Ts...>>, Ts...>
: std::true_type {};
template <typename... Ts>
concept has_common_type =
sizeof...(Ts) < 2 ||
has_common_type_impl<void, Ts...>::value;
template<typename... Ts> requires has_common_type<Ts...>
void foo(Ts&&... ts) {}
3.变量包中的make_array
函数make_array有一个待定的提议。有关是否仍需要make_array的讨论,请参阅这篇SO文章。
make_array
的一个简单实现如下:
template<typename... T>
constexpr auto make_array(T&&... values) requires has_common_type<T...> {
using TYPE = std::common_type_t<std::decay_t<T>...>;
return std::array<TYPE, sizeof...(T)>{static_cast<TYPE>(values)...};
}
以下使用示例:
constexpr auto arr1 = make_array(1, 2, 3);
constexpr auto arr2 = make_array(1, 2.5, 3);
using namespace std::string_literals;
auto arr3 = make_array("hello"s, "world");
注意,make_array
的提案可以选择提供实际请求的类型,但如果没有提供,则使用common_type
。
- "type* = nullptr"的含义是什么
- 警告的原因是什么:"when type is in parentheses, array cannot have dynamic size"?
- C++ - "Incomplete type not allowed"错误是什么意思,我该如何修复它?
- 这是什么意思:"member reference type 'Human *' is a pointer; did you mean to use '->'?"
- C++ 中数组的"expression must have pointer-to-object type"是什么?
- "conversion from void to non scalar type string"是什么意思?
- 在 LLVM 中,调用中函数的位播"type"是什么?如何访问此功能?
- C++中的"vector<type[n]>"是什么?
- "type-safety"在C++中的确切含义是什么?
- 在OpenCV中,std::vector而不是cv::Mat的"type"是什么解释,我该如何更改它?(C++)
- c++ 声明中的 ::type 是什么意思
- "Cannot overload functions distinguished by return type alone"是什么意思?
- cmake -D <var>:<type>=<value> 参数"-D"是什么意思
- C++:声明'TYPE& name(&TYPE);'是什么意思?
- 这个错误是什么意思" expression must have pointer-to-class type"?
- 错误是什么意思"expression must have class type"?
- 'must have an argument of class or enumerated type'到底是什么意思
- "Expected '(' for function-style cast or type construction"错误是什么意思?
- &Type::变量是什么意思?
- 这个论点的声明是什么意思:"type (*name1) (const type& name2)"?