将auto关键字替换为推导类型(clang或VS2010) [英] Replace auto keyword with deduced type (clang or VS2010)

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

问题描述

有没有人编写一个脚本,插件或可执行文件,用编译器推导的类型替换每个'auto'实例?我需要端口一些C ++ 11代码,使用自动所有的地方。



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



另一种方法是从编译器解析错误,因为预期类型可能在错误输出中。我可以 -Dauto = int 并且可能回到无法将std :: vector< int> :: iterator转换为'int' code>

解决方案

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

 模板< 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 ,附带地包含相同名称的typedef > iterator ),因此 typename T :: iterator it 将在这里工作,但你可以实例化 foo



在标准库类中添加了很多typedef,以允许在 auto 被发明/重新使用之前编写这样的模板,你可以做同样的事情来处理一个没有 auto 的编译器。但它不是你可以自动化,至少不是没有努力相当于添加支持 auto 到编译器...



即使 auto 不依赖于模板类型,将其替换为对用户有意义并且可移植的一个难题。取:

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

auto 的合理替换为 std :: 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


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 is my first candidate. Has anyone modified it to do something like this?

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

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.

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...

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

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.

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

error: cannot convert __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > to int in initialization

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆