这里有一些关于
std::common_type
的用例:
1. 可变参数包的总和
这里是一个需要使用common_type
的可变参数总和版本:
template<typename... T>
constexpr auto sum(T&&... values) {
std::common_type_t<T...> sum {};
static_for<sizeof...(T)>([&](auto index) {
sum += get<index>(values...);
});
return sum;
}
上面的例子使用了来自
this和
this的机器设备。
注意:你可以使用以下代码来实现相同的功能,而不需要使用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. 要求可变参数包具有公共类型
下面的代码 基于 这个 Stack Overflow 帖子。
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
。
common_type
不能对common_type<Bar, Foo>
产生答案,但我认为这很有用和直观。 - pmrcommon_type<A,B>::type
可用,其中至少有一个A
和B
是该函数模板的模板参数,则该函数不会被视为common_type<A,B>::type
的重载分辨率有效。如果您提供函数的另一种重载,则将选择该重载。 - Anthony Williamscommon_type<Bar, Foo>::type
输出Baz
,那么你必须自己专门定义common_type
。否则,编译器怎么知道从Foo
和Bar
构造出的众多类型中使用哪一个呢?例如:boost::any
可以从任何东西构造。 - Anthony Williamscommon_type
更多地是供库构建者使用的工具,而不是供库用户使用的工具。通常情况下,库用户只有在库作者将common_type
设计到库接口中时才会使用它。库作者可以根据common_type
是否真正对他的库有用来选择是否使用它。 - Howard Hinnant