推导指南中的引用和值之间的差异
Difference between references and values in deduction guides
考虑类型 A
:
template <typename T, size_t N>
struct A
{
T arr[N];
};
C++17用户自定义有什么区别deduction guides
template <typename T, typename ... Ts>
A(const T&, const Ts& ...) -> A<T, 1 + sizeof...(Ts)>;
和
template <typename T, typename ... Ts>
A(T, Ts ...) -> A<T, 1 + sizeof...(Ts)>;
?
或者换句话说,const引用和推导指南中的值有什么区别吗?
请注意,问题不是关于模板函数类型推导,而是关于新的 C++17 特性,用户定义的推导指南 class 模板参数推导,所以你可以简单地声明 A instance{1,2,3}
而不是 A<int, 3> instance{1,2,3}
.
Or, in other words is there any difference between const references and values in deduction guides?
在你的情况下可能不是,但一般来说,是的。
当 T
不可复制时。
在下面的示例中,第一种情况(const 引用)编译接收一个 std::unique_ptr<int>
,第二种情况(值)给出错误
#include <iostream>
#include <memory>
template <typename T, size_t N>
struct A
{ template <typename ... Ts> A (Ts const & ...) {} };
template <typename T, size_t N>
struct B
{ template <typename ... Ts> B (Ts const & ...) {} };
template <typename T, typename ... Ts>
A(T const &, Ts const & ...) -> A<T, 1U + sizeof...(Ts)>;
template <typename T, typename ... Ts>
B(T, Ts ...) -> B<T, 1 + sizeof...(Ts)>;
int main()
{
std::unique_ptr<int> up;
auto a = A{up}; // compile
// auto b = B{up}; // doesn't compile
}
不同之处在于,在推导指南中使用值时,参数将衰减以进行模板参数推导。例如,
#include <cstddef>
using std::size_t;
template <typename T, size_t N>
struct A
{
T arr[N];
};
template <typename T, typename ... Ts>
A(const T&, const Ts& ...) -> A<T, 1 + sizeof...(Ts)>;
template <typename T, size_t N>
struct B
{
T arr[N];
};
template <typename T, typename ... Ts>
B(T, Ts ...) -> B<T, 1 + sizeof...(Ts)>;
int main()
{
int test[42];
A instanceA {test}; // deduced to be A<int[42], 1>, error
B instanceB {test}; // deduced to be B<int*, 1>, ok but the effect may be unexpected
}
考虑类型 A
:
template <typename T, size_t N>
struct A
{
T arr[N];
};
C++17用户自定义有什么区别deduction guides
template <typename T, typename ... Ts>
A(const T&, const Ts& ...) -> A<T, 1 + sizeof...(Ts)>;
和
template <typename T, typename ... Ts>
A(T, Ts ...) -> A<T, 1 + sizeof...(Ts)>;
?
或者换句话说,const引用和推导指南中的值有什么区别吗?
请注意,问题不是关于模板函数类型推导,而是关于新的 C++17 特性,用户定义的推导指南 class 模板参数推导,所以你可以简单地声明 A instance{1,2,3}
而不是 A<int, 3> instance{1,2,3}
.
Or, in other words is there any difference between const references and values in deduction guides?
在你的情况下可能不是,但一般来说,是的。
当 T
不可复制时。
在下面的示例中,第一种情况(const 引用)编译接收一个 std::unique_ptr<int>
,第二种情况(值)给出错误
#include <iostream>
#include <memory>
template <typename T, size_t N>
struct A
{ template <typename ... Ts> A (Ts const & ...) {} };
template <typename T, size_t N>
struct B
{ template <typename ... Ts> B (Ts const & ...) {} };
template <typename T, typename ... Ts>
A(T const &, Ts const & ...) -> A<T, 1U + sizeof...(Ts)>;
template <typename T, typename ... Ts>
B(T, Ts ...) -> B<T, 1 + sizeof...(Ts)>;
int main()
{
std::unique_ptr<int> up;
auto a = A{up}; // compile
// auto b = B{up}; // doesn't compile
}
不同之处在于,在推导指南中使用值时,参数将衰减以进行模板参数推导。例如,
#include <cstddef>
using std::size_t;
template <typename T, size_t N>
struct A
{
T arr[N];
};
template <typename T, typename ... Ts>
A(const T&, const Ts& ...) -> A<T, 1 + sizeof...(Ts)>;
template <typename T, size_t N>
struct B
{
T arr[N];
};
template <typename T, typename ... Ts>
B(T, Ts ...) -> B<T, 1 + sizeof...(Ts)>;
int main()
{
int test[42];
A instanceA {test}; // deduced to be A<int[42], 1>, error
B instanceB {test}; // deduced to be B<int*, 1>, ok but the effect may be unexpected
}