本文介绍了用推导类型替换 auto 关键字(clang 或 VS2010)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人写过一个脚本、插件或可执行文件,用编译器推导出的类型替换每个 'auto' 实例?我需要移植一些在所有地方都使用 auto 的 C++11 代码.

Has anyone written a script, plugin, or executable that replaces each instance of 'auto' with the compiler-deduced type? I need to port some C++11 code that uses auto all over the place.

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

Clang is my first candidate. Has anyone modified it to do something like this?

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

An alternative is to parse the errors from a compiler as the expected type might be in the error output. I could -Dauto=int and possibly get back "could not convert std::vector<int>::iterator to 'int'"

推荐答案

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

Unfortunately, this is impossible in the general case. Consider:

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::mapstd::set 包含代表各自迭代器类型的同名类型定义 (iterator),所以 typename T::iterator it 可以在这里工作,但是您可以为没有这样的 typedef 的 T 实例化 foo.

Admittedly a pointless example, but it shows that there's no way to know what to replace auto with, when dependent on a template argument. std::map and std::set, incidentally, contain typedefs of the same name (iterator) that represent the type of the respective iterator, so typename T::iterator it would work here, but you can instantiate foo for a T that does not have such a typedef.

标准库类中的大量 typedef 被添加到允许在 auto 被发明/重新设计之前编写这样的模板,并且你可以做同样的事情来处理一个编译器没有 auto.但这不是你可以自动化的东西,至少不是像向编译器添加对 auto 的支持那样付出努力......

The numerous typedefs in the standard library classes were added exactly to allow such templates to be written before auto was invented/re-purposed, and you can do the same thing to deal with a compiler that doesn't have auto. But it's not something you can automate, at least not without an effort comparable to adding support for auto to a compiler...

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

Even when auto is not dependent on a template type, it is a difficult problem to replace it with something that makes sense to the user and is portable. Take:

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

auto 的合理替代是 std::map::iterator,但如果你使用 -Dauto=int> 并查看编译器错误消息,您可以将其替换为 std::_Rb_tree_iterator<std::pair<const int, int>>.这是标准库的实现细节,难以阅读,而且显然不可移植——你不希望在你的代码中.

The reasonable replacement for auto is std::map<int, int>::iterator, but if you use -Dauto=int and look at the compiler error messages, you'd replace it with something like std::_Rb_tree_iterator<std::pair<const int, int> >. That's implementation detail of the standard library, hard to read and obviously not portable -- you don't want that in your code.

在你的例子中,我的编译器(GCC 4.4.6)说:

In your very example, my compiler (GCC 4.4.6) says:

错误:无法转换__gnu_cxx::__normal_iteratorint 初始化

这篇关于用推导类型替换 auto 关键字(clang 或 VS2010)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 18:52