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)
有一些技巧可以让编译器向您展示typedef的实际类型.一种是尝试实例化一个不完整的类型.
template<typename>
struct Printer;
typedef std::vector<int> foobartype;
Printer<foobartype> printer;
Run Code Online (Sandbox Code Playgroud)
还有boost :: mpl :: print,它实际上可以发出警告而不是错误输出.
所有这些技术都必须在typename实际可访问的地方使用,因此您必须最终"跟踪"代码.
遗憾的是,调试模板代码几乎是一门黑色艺术,通常你必须玩编译器并在头脑中实例化以解决问题.