我一直在使用C ++ 0x的auto
关键字并尝试以下操作。
std::unique_ptr<auto> ptr(new int(0));
我尝试使用g ++ 4.4.5进行编译并获得
error: invalid use of auto
从眼睛上判断,auto
很容易被推断为int
。
我的猜测是类型推断,模板引擎不会相互通信。否则,模板引擎会知道使用int
作为类型参数来实例化模板类。
另一个猜测来自标准,我看到了这一点。
A member shall not be declared with auto, extern or register storage class.
但我认为那是auto
和局部变量一样,而不是auto
用来推断类型。
我最后的猜测是编译器认为这是一个auto
存储类,而不是类型推导的auto
。
标准中有这样的理由吗?
答案 0 :(得分:10)
那是因为它必须在确定如何处理其参数之前确定调用构造函数的类。如果你将构造函数作为模板,它就像任何其他模板函数一样工作 - 自动推理参数。
答案 1 :(得分:5)
@dascandy已正确识别您的代码有什么问题。我会尝试提供一些理由:
您期望编译器推断unique_ptr<int>
因为参数是int*
,而unique_ptr<int>
有一个接受int*
的构造函数。暂时让我们忽略我们使用std::unique_ptr
的事实,然后谈谈我们编写的模板类(并且可以专门化)。
编译器为什么要推断unique_ptr<int>
?参数不是int
,而是int*
。为什么不猜它unique_ptr<int*>
?当然这会导致编译器错误,因为unique_ptr<int*>
的构造函数不会接受int*
。除非我添加专业化:
template<>
class unique_ptr<int*>
{
public:
unique_ptr(int*) {}
};
现在unique_ptr<int*>
会编译。编译器应该如何知道选择哪个,unique_ptr<int>
或unique_ptr<int*>
?如果我添加另一个专业化怎么办?
template<>
class unique_ptr<double>
{
public:
unique_ptr(int*) {}
};
编译器现在有三个选项可供选择,它必须使用每个可能的参数实例化模板才能找到它们。显然这是不可行的,特别是对于多个模板参数和模板递归。
您可以做的是创建一个将推断类型连接到一个模板实例的工厂函数:
template<typename T>
std::unique_ptr<T> make_unique(T* arg) { return arg; }
(当然,这不起作用,因为unique_ptr
无法复制。但这个想法是有效的,并在例如make_shared
和make_pair
中使用。)
极端丑陋的一些例子:
有人可能会说unique_ptr<shared_ptr<int>>
是此代码的有效匹配。
或者怎么样:
template<typename T>
class unique_ptr
{
public:
explicit unique_ptr(T* arg);
unique_ptr(int*, enable_if<(sizeof(T) > 16)>::type* = 0);
};
答案 2 :(得分:2)
只想添加大多数情况下已存在的解决方案:
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));
显然有点夸张,但你明白了。这些“发电机功能”非常普遍。
答案 3 :(得分:2)
为标准提出了这个(或类似的) 。拟议的功能看起来像:
std::vector<int> GetMahVector();
std::vector<auto> var = GetMahVector();
然而,它被拒绝了。为什么它被拒绝了,如果可能的话,你必须挖掘相关的标准流程文档。