在C++中编译时输出typedef的类型(特别是在发生错误时)

Sam*_*rsa 5 c++ templates typedef

我很难解释这个特定的问题/问题所以请耐心等待(我的模板相关问题都出了问题!).

以此代码为例(请注意,显示代码的方法是显示复杂的模板层次结构,而不是它是否有意义):

#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;
}
Run Code Online (Sandbox Code Playgroud)

并假设这是你得到的错误

3个重载中没有一个可以转换所有参数类型

请注意,我知道在这种情况下,如果您编译代码,错误消息与上面的不同,但我目前正在处理的复杂模板代码中的错误消息如上所述.我刚刚提供了一个简化的例子来帮助解决这个问题.

现在我想知道的类型Foo,即value_type,value_type1,value_type2这样我就可以修正这个错误,没有一路追溯中间人.我不想手动跟踪的原因是代码可能是非常复杂的模板代码,其中回溯非常困难.

我想,因为编译器已经找出了类型,它应该能让我知道,即应该有一个简单的方法来在编译时(可能通过输出窗口中的消息)找出附加到的类型typedef秒.有一个简单的方法吗?


解决方案编辑:这是另一个例子,可以在阅读所选答案后帮助未来的SOer:

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; 
}
Run Code Online (Sandbox Code Playgroud)

Visual C++ 2008的输出:

error C2079: 'test' uses undefined struct 'incomplete<T>'
1>        with
1>        [
1>            T=float
1>        ]
Run Code Online (Sandbox Code Playgroud)

pmr*_*pmr 7

有一些技巧可以让编译器向您展示typedef的实际类型.一种是尝试实例化一个不完整的类型.

template<typename>
struct Printer;

typedef std::vector<int> foobartype;
Printer<foobartype> printer;
Run Code Online (Sandbox Code Playgroud)

还有boost :: mpl :: print,它实际上可以发出警告而不是错误输出.

所有这些技术都必须在typename实际可访问的地方使用,因此您必须最终"跟踪"代码.

遗憾的是,调试模板代码几乎是一门黑色艺术,通常你必须玩编译器并在头脑中实例化以解决问题.