Dan*_*ica 6 c++ arrays templates template-argument-deduction c++17
扣除指南std::array要求所有类型都相同:
std::array arr = { 1, 2, 3.4 }; // error
Run Code Online (Sandbox Code Playgroud)
这种要求背后的理由是什么?如果允许使用不同的类型,是否会有任何重大缺陷?例如:
namespace std {
template <typename... T>
array(T...) -> array<std::common_type_t<T...>, sizeof...(T)>;
}
std::array arr = { 1, 2, 3.4 }; // decltype(arr)::value_type deduced as double
Run Code Online (Sandbox Code Playgroud)
T.C*_*.C. 10
有大量的设计问题使用common_type.例如std::common_type_t<A, B, C>,std::common_type_t<C, A, B>而std::common_type_t<C, B, A>不必都存在-如果他们这样做,不必是相同的类型:
struct A;
struct B;
struct C;
struct A { operator B(); };
struct B { operator C(); };
struct C { operator A(); };
static_assert(std::is_same_v<std::common_type_t<A, B, C>, C>);
static_assert(std::is_same_v<std::common_type_t<C, A, B>, B>);
static_assert(std::is_same_v<std::common_type_t<C, B, A>, A>);
Run Code Online (Sandbox Code Playgroud)
当重新排序初始化程序的元素导致推断出不同的类型(或发出错误)时,这会产生"有趣的"用户体验.
它与函数模板参数的推导方式相匹配.
如果它们产生多于一个可能的推导
A,则类型推断失败.
例如
template<typename T>
void foo(T, T){}
template<typename T>
struct bar{ bar(T, T) {} };
int main()
{
foo(1, 1.5); // error, note: deduced conflicting types for parameter 'T' ('int' and 'double')
bar(1, 1.5); // error, note: deduced conflicting types for parameter 'T' ('int' and 'double')
}
Run Code Online (Sandbox Code Playgroud)
但是您可以提供常见类型的演绎指南.
template<typename T>
struct baz{ baz(T, T) {} };
template<typename T, typename U>
baz(T, U) -> baz<std::common_type_t<T, U>>
Run Code Online (Sandbox Code Playgroud)
或重载转发到常见类型
template<typename T>
void quux(T, T){}
template<typename T, typename U>
std::enable_if_t<!std::is_same<std::decay_t<T>, std::decay_t<U>>> quux(T t, U u)
{
using C = std::common_type_t<T, U>;
quux<C>(std::forward<C>(t), std::forward<C>(u)); // I think this is right
}
int main()
{
baz(1, 1.5);
quux(1, 1.5);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
488 次 |
| 最近记录: |