Derive the typedef type at compile time in C ++ (especially when an error occurs)

It is very difficult for me to explain this particular problem / question, so please bear with me (I have problems with all questions related to the template!).

Take this code as an example (note that the code show point is to show a complex hierarchy of templates, does it make sense):

#include <string> #include <vector> #include <list> template <typename T> struct Foo { typedef typename T::value_type value_type; typedef typename T::value_type1 value_type1; typedef typename T::value_type2 value_type2; Foo() {} Foo(value_type1, value_type, value_type2) {} Foo(value_type, value_type1, value_type2) {} }; template <typename T, typename T1, typename T2> struct MiddleMan { typedef T value_type; typedef T1 value_type1; typedef T2 value_type2; }; template <typename T> struct MainClass { typedef typename T::value_type value_type; typedef typename T::value_type1 value_type1; typedef typename T::value_type2 value_type2; typedef MainClass<T> this_type; typedef Foo<this_type> iterator; }; using namespace std; int main() { typedef MiddleMan<string, vector<string>, list<vector<string> > > mm; MainClass<mm>::iterator a(1, 2, 3); return 0; } 

and suppose this is the error you get

None of the three overloads can convert all types of arguments

Please note that in this case I know that if you compile the code, the error message is different from the error message, but the error message in my complex code template that I am working on is above. I just presented a simplified example to help with the question.

Now I want to know the types of Foo , i.e. value_type , value_type1 , value_type2 so that I can fix the error without returning fully to MiddleMan. The reason I don't want to trace manually is because the code can be quite complex template code, where it is very difficult to do backtracking.

I realized that since the compiler has already parsed the types, it should be able to tell me, i.e. There should be an easy way to understand this at compile time (perhaps through a message in the output window) types attached to typedef s. Is there an easy way?


EDIT SOLUTION: Here is another example that can help future SOER after reading the selected answer:

 template <typename T> struct incomplete; template <typename T, typename T2, typename T3> class foo { public: typedef T value_type; typedef T2 value_type2; typedef T3 value_type3; }; int main() { // Assume the following type is much more complex typedef foo<float, int, char> type_i_am_having_trouble_with; // At this point you are instantiating it, and the program compiles (or maybe // not) and you have no idea what some of the typedefs stand for type_i_am_having_trouble_with b; // Use this to find out what the typedefs stand for incomplete<type_i_am_having_trouble_with::value_type> test; } 

Conclusion from Visual C ++ 2008:

 error C2079: 'test' uses undefined struct 'incomplete<T>' 1> with 1> [ 1> T=float 1> ] 
+4
source share
1 answer

There are several tricks to get the compiler to show you the actual typedef type. One of them is to try to create an instance of an incomplete type.

 template<typename> struct Printer; typedef std::vector<int> foobartype; Printer<foobartype> printer; 

There is also boost :: mpl :: print , which can actually issue a warning instead of an error.

All of these methods should be used where the type name is really available, so you will have to "track" the code in the end.

Unfortunately, debugging template code is pretty much black art, and often you will have to play the compiler and create things in your head to solve this problem.

+7
source

Source: https://habr.com/ru/post/1392277/


All Articles