13

有没有人写过一个脚本、插件或可执行文件,用编译器推断的类型替换“auto”的每个实例?我需要移植一些到处使用 auto 的 C++11 代码。

Clang 是我的第一个候选人。有没有人修改它来做这样的事情?

另一种方法是从编译器解析错误,因为预期的类型可能在错误输出中。我可以-Dauto=int而且可能会回来"could not convert std::vector<int>::iterator to 'int'"

4

1 回答 1

8

不幸的是,这在一般情况下是不可能的。考虑:

template <typename T> void foo(T & t)
{
    auto it = t.find(42);
    ...
}
...
std::map<int, int> m;
std::set<int> s;
...
foo(m);
foo(s);

诚然,这是一个毫无意义的例子,但它表明当依赖于模板参数时,无法知道用什么替换 auto 。 std::map和,顺便说一句,包含代表相应迭代器类型的std::set同名 ( ) 类型定义,因此可以在这里工作,但您可以为没有此类类型定义的 a实例化。iteratortypename T::iterator itfooT

标准库类中的大量 typedef 完全是为了允许在auto发明/重新使用之前编写此类模板,并且您可以做同样的事情来处理没有auto. 但这不是你可以自动化的东西,至少不是没有与添加对auto编译器的支持相当的努力......

即使auto不依赖于模板类型,用对用户有意义且可移植的东西替换它也是一个难题。拿:

std::map<int, int> m;
auto it = m.find(42);

的合理替换autostd::map<int, int>::iterator,但是如果您使用-Dauto=int并查看编译器错误消息,您会用类似的东西替换它std::_Rb_tree_iterator<std::pair<const int, int> >。那是标准库的实现细节,难以阅读并且显然不可移植——你不希望你的代码中使用它。

在您的示例中,我的编译器(GCC 4.4.6)说:

错误:无法在初始化中转换__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >int

于 2012-01-20T17:59:25.553 回答