Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++_Templates_C++11 - Fatal编程技术网

C++ 为什么可以';是否不能将“自动”用作模板类型参数?

C++ 为什么可以';是否不能将“自动”用作模板类型参数?,c++,templates,c++11,C++,Templates,C++11,我一直在使用C++0x的auto关键字,并尝试了以下方法 std::unique_ptr<auto> ptr(new int(0)); 通过肉眼判断,auto可以很容易地推断为int 我的猜测是类型推断和模板引擎不会相互对话。否则,模板引擎将知道使用int作为类型参数实例化模板类 另一个猜测来自标准,我看到了 A member shall not be declared with auto, extern or register storage class. 但我认为这是局部变量

我一直在使用C++0x的
auto
关键字,并尝试了以下方法

std::unique_ptr<auto> ptr(new int(0));
通过肉眼判断,
auto
可以很容易地推断为
int

我的猜测是类型推断和模板引擎不会相互对话。否则,模板引擎将知道使用
int
作为类型参数实例化模板类

另一个猜测来自标准,我看到了

A member shall not be declared with auto, extern or register storage class.
但我认为这是局部变量中的
auto
,而不是用于推断类型的
auto

我最后的猜测是编译器认为这是一个
auto
存储类,而不是用于类型推断的
auto


标准中有这样规定的原因吗?

这是因为它必须先确定调用构造函数的类,然后再确定如何处理其参数。如果将构造函数设置为模板,它将与任何其他模板函数一样工作—自动推断参数。

@dascandy已正确识别代码中的错误。我将尝试提供一些基本原理:

您希望编译器推断出
unique\u ptr
,因为参数是
int*
,并且
unique\u ptr
有一个接受
int*
的构造函数。让我们暂时忽略一个事实,即我们使用的是
std::unique\u ptr
,只讨论我们编写的模板类(并且可以专门化)

为什么编译器要推断出
唯一的\u ptr
?参数不是
int
,而是
int*
。为什么它不应该猜测
唯一性\u ptr
?当然,这会导致编译器错误,因为
unique\u ptr
的构造函数不会接受
int*
。除非我添加了专门化:

template<>
class unique_ptr<int*>
{
public:
    unique_ptr(int*) {}
};

只想补充一点,大多数情况下已经存在解决方案:

template <typename T>
std::unique_ptr<T> unique_ptr_auto(T* ptr)
{
    // fails to handle std::unique_ptr<T[]>, not deducible from pointer
    return std::unique_ptr<T>(ptr);
}

auto ptr = unique_ptr_auto(new int(0));
模板
std::unique_ptr unique_ptr_auto(T*ptr)
{
//无法处理std::unique_ptr,无法从指针推断
返回std::unique_ptr(ptr);
}
自动ptr=唯一的ptr自动(新整数(0));
显然有点冗长,但你明白了。这些“发电机功能”非常常见。

这(或类似)是为标准提出的。建议的功能类似于:

std::vector<int> GetMahVector();
std::vector<auto> var = GetMahVector();
std::vector GetMahVector();
std::vector var=GetMahVector();

然而,它被拒绝了。为什么被拒绝,如果可能的话,您必须挖掘相关的标准流程文档。

正确--类型推断不适用于模板类。通常,您最终使用工厂函数作为解决方法,例如
auto ptr(make_unique(new int(0))注意:引用“成员不应…”不是来自C++0X<代码>自动
不是该标准中的存储类说明符。N3290:“不得向外部或注册存储类规范声明成员。”也可以是
std::unique_ptr ptr ptr(新int(0))
和std::unique\u ptr都有一个取int*的构造函数。请注意,即使是
newint[100000000]
在事实发生后仍然看起来像
int*
。这个问题是语言的基础。解决方案将要求数组真正具有自己的类型,因此动态分配的数组将是数组类型,而不是指针类型。这只是在谈论
std::unique_ptr(…)
,谁知道这个问题的一般情况。@托马斯:这在C++03中是正确的,但在C++0x中不是。”它必须用每个可能的参数实例化模板,以便找到它们“否,因为它已经知道存在哪些专门化。也就是说,这在一般情况下是不明确的,因为两个专门化都可能有模板构造函数,所以两者都不可取。对于某些类模板来说这是可行的,但我怀疑它只在一般情况下的一部分时间有效。如果一个复杂的特性应该被添加到语言中,那么它应该在大部分或所有时间都有效;正如你所说的,太复杂了,不可行。<代码>模板STD::UnQuyJPPTMACHONIONE(T*ARG){返回STD::UnQuyjpTR(ARG);}将工作得很好,因为<代码> UnQuyPPTR <代码>是可移动的(但是它的构造函数是“代码>显式< /代码>”)@ gman:考虑部分特化和模板递归……可能引入的专门化的数量是无限的。使用
enable\u if
和类型特征的模板怎么样?在一般情况下,编译器必须用每一个可能的参数进行实例化。@Ben:仍然需要检查有限数量的专门化。如果不是这样的话,编译器将根本无法处理它们。@GMan:现在,需要检查的专门化数量有限,因为模板参数是由程序员提供的。@Ben Voigt:不是,但不一定要让这个特定的代码示例正确运行。啊,所以它实际上在某处被记录了下来。非常感谢。这个受限版本不会很有用,您可以说
auto var=GetMahVector()@BenVoigt在某些情况下对于可编性肯定是有用的。目前针对这种语法的建议(对于C++17)是。该提案包含了所有与模板相关的内容,但这种语法也隐藏在其中。
template<typename T>
std::unique_ptr<T> make_unique(T* arg) { return arg; }
template<typename T>
class unique_ptr
{
public:
    explicit unique_ptr(T* arg);
    unique_ptr(int*, enable_if<(sizeof(T) > 16)>::type* = 0);
};
template <typename T>
std::unique_ptr<T> unique_ptr_auto(T* ptr)
{
    // fails to handle std::unique_ptr<T[]>, not deducible from pointer
    return std::unique_ptr<T>(ptr);
}

auto ptr = unique_ptr_auto(new int(0));
std::vector<int> GetMahVector();
std::vector<auto> var = GetMahVector();