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

后端 未结 5 1501
悲&欢浪女
悲&欢浪女 2021-01-11 10:10

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 f

相关标签:
5条回答
  • 2021-01-11 10:43

    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.

    0 讨论(0)
  • 2021-01-11 10:44

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

    auto x = 5 + 7;
    

    becomes

    BOOST_AUTO(x,5+7);
    
    0 讨论(0)
  • 2021-01-11 10:59

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

    0 讨论(0)
  • 2021-01-11 11:00

    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.

    0 讨论(0)
  • 2021-01-11 11:07

    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.

    0 讨论(0)
提交回复
热议问题