繁体   English   中英

为什么不能自动用作模板类型参数?

[英]Why can't auto be used as a template type parameter?

我一直在玩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类型推导。

标准中有这样的理由吗?

那是因为它必须确定如何处理其参数之前确定调用构造函数的类。 如果你将构造函数作为模板,那么它就像任何其他模板函数一样工作 - 自动推理参数。

@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_sharedmake_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);
};

只想添加大多数情况下已存在的解决方案:

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();

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM