将 auto 关键字替换为推导类型(clang 或 VS2010)

发布于 2024-12-27 20:43:26 字数 257 浏览 0 评论 0 原文

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

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

另一种方法是解析来自编译器的错误,因为错误输出中可能包含预期类型。我可以 -Dauto=int 并可能返回 “无法将 std::vector::iterator 转换为 'int'”

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'"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

z祗昰~ 2025-01-03 20:43:26

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

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 包含同名的 typedef (iterator),它们表示各自迭代器的类型,因此 typename T::iterator it 可以在这里工作,但是您可以为没有此类 typedef 的 T 实例化 foo

标准库类中的大量 typedef 被精确地添加,以允许在发明/重新利用 auto 之前编写此类模板,并且您可以做同样的事情来处理不支持的编译器有自动。但这不是您可以自动化的东西,至少不需要付出与向编译器添加对 auto 的支持相当的努力......

即使 auto 不依赖于模板类型,用对用户有意义且便携的东西来替代它是一个难题。采取:

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

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

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

错误:无法转换 __gnu_cxx::__normal_iterator; > >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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文