2016-11-28 76 views
-4
#include <iostream> 
using namespace std; 
class A{ 
public: 
     void K() 
     { 
      cout<<"1"; 
     }; 
}; 
class B{ 
public: typedef A T; 
     void K() 
     { 
      cout<<"2"; 
     }; 
}; 
class C{ 
public: 
     void K() 
     { 
      cout<<"3"; 
     }; 
}; 
class D{ 
    public: 
    void K() 
    { 
     cout<<"4"; 
    }; 
}; 
template <class D=A> class E{ 
public: typedef D T; 
    void K() 
    { 
     cout<<"5"; 
    }; 
}; 
template <> class E<A>{ 
public:typedef C T; 
    void K() 
    { 
     cout<<"6"; 
    }; 
}; 
template <>class E<C>{ 
public:typedef B T; 
    void K() 
    { 
     cout<<"7"; 
    }; 
}; 
template <class W, class V=E<W> > 
class F{ 
typedef typename V::T R; 
public: 
    void K() 
    { 
     V().K(); 
     W().K(); 
     R().K(); 
    }; 
}; 
    int main(){ 
    E<>().K(); 
    F<A>().K(); 
    F<C>().K(); 
    return 0; 
} 

我不知道为什么程序输出是6 - 612 - 732.如果有人可以帮助我这个程序如何工作,这将是很棒的,即使是第一行主。如果有人能够告诉我为什么第一个cout是一步一步的,那该多好。程序输出与模板和typedef类

+2

解决此类问题的正确工具是您的调试器。在*堆栈溢出问题之前,您应该逐行执行您的代码。如需更多帮助,请阅读[如何调试小程序(由Eric Lippert撰写)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。至少,你应该[编辑]你的问题,包括[最小,完整和可验证](http:// stackoverflow。com/help/mcve)示例,它再现了您的问题以及您在调试器中的观察结果。 –

+2

[这是否澄清了多一点?](http://coliru.stacked-crooked.com/a/a58abdf4e557a8ae) –

回答

0

这将由于模板排序规则。让我们仔细检查一下事情。

int main(){ 
    E<>().K(); // Line 1. 
    F<A>().K(); // Line 2. 
    F<C>().K(); // Line 3. 
    return 0; 
} 

1号线:

这里,我们试图匹配模板模式E<>。我们的选项是:

// Primary template. 
template <class D=A> class E{ 
public: typedef D T; 
    void K() 
    { 
     cout<<"5"; 
    }; 
}; 

// Specialisation for A. 
template <> class E<A>{ 
public:typedef C T; 
    void K() 
    { 
     cout<<"6"; 
    }; 
}; 

// Specialisation for C. 
template <>class E<C>{ 
public:typedef B T; 
    void K() 
    { 
     cout<<"7"; 
    }; 
}; 

编译器检查主模板,并看到默认参数是A;它因此填补了空白,将模板解析为E<A>。这使它匹配其中一个专业化,以便选择专业化。

E<>().K(); // Calls E<A>::K(). 

线路2

与线1中,由于未指定参数中的一个,编译器填补空白,解决模板F<A, E<A>>。因此,WA,VE<A>,并且R是E<A>::TC。这解决下列功能被调用:

template <class W, class V=E<W> > 
class F{ 
typedef typename V::T R; 
public: 
    void K() 
    { 
     V().K(); // Calls E<A>::K(). 
     W().K(); // Calls A::K(). 
     R().K(); // Calls C::K(). 
    }; 
}; 

第3行:

与第2行中,编译器在空白填充,解析到F<C, E<C>>。因此,WC,VE<C>,并且RE<C>::TB。这解析为被称为以下功能:

template <class W, class V=E<W> > 
class F{ 
typedef typename V::T R; 
public: 
    void K() 
    { 
     V().K(); // Calls E<C>::K(). 
     W().K(); // Calls C::K(). 
     R().K(); // Calls B::K(). 
    }; 
}; 

现在,我们已经解决了模板...

int main(){ 
    E<>().K(); // E<A>::K(). 
    F<A>().K(); // F<A, E<A>>::K() -> E<A>::K(), A::K(), C::K(). 
    F<C>().K(); // F<C, E<C>>::K() -> E<C>::K(), C::K(), B::K(). 
    return 0; 
} 

因此输出是...

6613732 

[注:如果你的编译器给你输出6612732,它不应该。铿锵声,GCC和MSVC都同意,这里的正确输出是6613732。]

+0

是的,正确的输出是真的6613732,我的坏。非常感谢你的时间,并帮助我! – redizzar

+0

@PatrikTóth不客气。 –