Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 扣减指南中参考值和值之间的差异_C++_Language Lawyer_C++17_Variadic Templates_Template Argument Deduction - Fatal编程技术网

C++ 扣减指南中参考值和值之间的差异

C++ 扣减指南中参考值和值之间的差异,c++,language-lawyer,c++17,variadic-templates,template-argument-deduction,C++,Language Lawyer,C++17,Variadic Templates,Template Argument Deduction,考虑类型A: template <typename T, size_t N> struct A { T arr[N]; }; 模板 结构A { T arr[N]; }; C++17用户定义的 模板 A(常数T&,常数Ts&…)->A; 及 模板 A(T,Ts…)->A; ? 或者,换句话说,常量引用和演绎指南中的值之间是否存在任何差异 请注意,问题不是关于模板函数类型推断,而是关于新的C++17特性,即类模板参数推断的用户定义推断指南,因此您可以简单地声明实例{1,

考虑类型
A

template <typename T, size_t N>
struct A
{
    T arr[N];
};
模板
结构A
{
T arr[N];
};
C++17用户定义的

模板
A(常数T&,常数Ts&…)->A;

模板
A(T,Ts…)->A;
?

或者,换句话说,常量引用和演绎指南中的值之间是否存在任何差异


请注意,问题不是关于模板函数类型推断,而是关于新的C++17特性,即类模板参数推断的用户定义推断指南,因此您可以简单地声明
实例{1,2,3}
,而不是
实例{1,2,3}

或者,换句话说,常量引用和演绎指南中的值之间是否存在任何差异

在你的情况下,也许不是,但一般来说,是的

T
不可复制时

在下面的示例中,第一种情况(const reference)编译接收到一个
std::unique_ptr
,第二种情况(value)给出一个错误

#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
 }
#包括
#包括
模板
结构A
{模板A(Ts常数&…){};
模板
结构B
{模板B(Ts常数&…){};
模板
A(T常数&,Ts常数&…)->A;
模板
B(T,Ts…)->B;
int main()
{
std::唯一的ptr up;
自动a=a{up};//编译
//自动b=b{up};//不编译
}

不同之处在于,当在演绎指南中使用值时,模板参数演绎的参数将衰减。比如说,

#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
}
#包括
使用std::size\u t;
模板
结构A
{
T arr[N];
};
模板
A(常数T&,常数Ts&…)->A;
模板
结构B
{
T arr[N];
};
模板
B(T,Ts…)->B;
int main()
{
int检验[42];
instanceA{test};//推断为,错误
B instanceB{test};//推断为B,可以,但效果可能是意外的
}

很有趣。我没想过。既然构造器还可以(引用),我想应该没有问题。好主意。@bolov-works也是
B
构造函数的复制品;但是对问题中的
A
不起作用(因为数组
arr
的初始化需要拷贝)
auto b=b{up}
compiles.[over.best.ics]/2:“忽略其他属性,例如生存期、存储类、对齐方式、参数的可访问性、参数是否是位字段以及函数是否被删除。”@xskxzr-我不是标准的专家,但我不认为您引用的片段说
auto b=b{up}正常;如下(我正在阅读C++17标准,so 16.3.3.1.2)“因此,尽管可以为给定的参数对定义隐式转换序列,但从参数到参数的转换在最终分析中可能仍然是错误的”。我想是这样的:选择了一个已删除的函数(拷贝构造函数为<代码> STD::UnQuyJPPT),所以代码是“最终形成的”,但我重复:我不是专家,所以我会为C++ Guuru准备一个不同的问题。
#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
}