Retrieving the type of auto in C++11 without executing the program

半世苍凉 提交于 2019-12-22 02:03:37

问题


I have some C++11 code using the auto inferred type that I have to convert to C++98. How would I go about converting the code, substituting in the actual type for all instances of auto?


回答1:


It is going to be a PITA, but you can declare an incomplete struct template accepting a single type parameter.

Given the variable x you want to know the type of, you can use the struct with decltype(x) and that will lead to a compiler error that will show you the inferred type.

For example:

template<class Type> struct S;

int main() {
    auto x = ...;
    S<decltype(x)>();
}

Live demo

which will produce an error message in the form:

error: implicit instantiation of undefined template 'S<X>' (clang++)
error: invalid use of incomplete type 'struct S<X>' (g++)

with X being the inferred type. In this particular case the type is int.

Trivia: This has been recommended by Scott Meyer in one of the recent NDC 2014's videos (I don't remember which one).




回答2:


As auto is known at compile-time, you need to interoperate with the compiler.

One option would be the Clang compiler's LibTooling library that provides infrastructure that you can base static analysis tools on. For example, look at their refactoring example code that removes superfluous .c_str() calls from the code. I think you could write a similar tool that converts auto into the inferred type.




回答3:


You can try to use the BOOST_AUTO macro in the Boost typeof library.

auto x = 5 + 7;

becomes

BOOST_AUTO(x,5+7);



回答4:


You could use typeid and std::type_info::name();

#include <iostream>
#include <typeinfo>
#include <complex>

int
main()
{
  using namespace std::literals::complex_literals;

  auto x = 3.1415F;
  std::cout << typeid(x).name() << '\n';
  auto z = 1.0 + 1.0i;
  std::cout << typeid(z).name() << '\n';
}

$ /home/ed/bin_concepts/bin/g++ -std=c++14 typeid.cpp 

$ ./a.out
f
St7complexIdE

The names aren't beautiful but you can at least translate them. These names are got from g++. The name is compiler dependent. There is some movement to standardize a pretty_name(). Here is a non-standard way to unmangle the names.




回答5:


An alternative approach would be to use function templates and type deduction. It may not work in all examples you have but it may help in some cases:

int foo ()
{
   auto x = bar();
   // do something with 'x'
}

Change this to:

template <typename T> int foo_(T x)
{
   // do something with 'x'
}

int foo ()
{
   foo_(bar());
}

auto is specified in terms of type deduction, so the above should have very similar, if not identical semantics as the C++ '11 version.



来源:https://stackoverflow.com/questions/24441505/retrieving-the-type-of-auto-in-c11-without-executing-the-program

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!