2016-11-09 93 views
2

我有以下模板类&示例类:如何设置,作为默认模板参数,嵌套模板类instanciation取决于其他参数

template<typename A, typename B, typename C = typename A::Nested<B>> 
struct X 
{ 
    X() 
    { 
     std::cout << "A is : " << A::who() << std::endl; 
     std::cout << "B is : " << B::who() << std::endl; 
     std::cout << "C is : " << C::who() << std::endl; 
    } 
}; 

struct Bsample 
{ 
    static const char* who() { return "Bsample"; } 
}; 

struct Asample 
{ 
    template<typename B> 
    struct Nested; 
    template<> 
    struct Nested<Bsample> 
    { 
     static const char* who() { return "Asample::Nested<Bsample>"; } 
    }; 
    static const char* who() { return "Asample"; } 
}; 

当使用VCl 4,以上代码编译就好,并产生预期的行为为X<Asample, Bsample>默认模板参数CAsample::Nested<Bsample>的实例。

然而,GCC 5.1编译时,我得到以下错误:

prog.cpp:4:65: error: expected '>' before '<' token 
template<typename A, typename B, typename C = typename A::Nested<B>> 
                   ^

我试了几个组合,以申报模板参数C默认值,使用templatetypename,...但没有成功地使用GCC编译此代码。

如何使此代码符合C++标准并使用GCC进行编译?

感谢您的帮助

编辑:除了从TartanLlama

除了从TartanLlama接受的答案接受的答案,我也只好终止模板参数brakets之间插入空白(空间) :

template<typename A, typename B, typename C = typename A::Nested<B> > 
//          blank (space) added here^

否则,GCC将发出以下错误(未指定选项-std=c++11时):

error: spurious '>>', use '>' to terminate a template argument list 
template<typename A, typename B, typename C = typename A::template Nested<B>> 
                      ^
+0

我投票重新开放,因为这不仅仅是'template'和'typename',它似乎像OP知道他们的使用,但不知道如何在这里应用它。 – TartanLlama

+0

@TartanLlama:可悲的是,有些人比光明更快地解决问题,甚至没有把它们读到最后......(我有一个想法,迄今为止谁已经关闭了我。)谢谢你重新开放。 – shrike

回答

4

同时需要typenametemplate这里:

template<typename A, typename B, typename C = typename A::template Nested<B>> 

template说比A::Nested是一个模板,以及typenameA::Nested<B>名称的类型。

您还需要移动的Asample::Nested专业化出Asample定义的:

struct Asample 
{ 
    template<typename B> 
    struct Nested; 

    static const char* who() { return "Asample"; } 
}; 

template<> 
struct Asample::Nested<Bsample> 
{ 
    static const char* who() { return "Asample::Nested<Bsample>"; } 
}; 

Live demo

+0

我实际上是在你的答案中尝试声明默认的模板参数,但是仍然有一个来自gcc的奇怪错误:'spurious'>>',使用'>'来终止模板参数列表。我只是明白,gcc确实将最终'>>'解释为提取操作符;在关闭的刹车之间插入一个空白处理问题。 (如果您愿意,您可以更新您的答案以提及此问题;否则我会更新我的问题。)无论如何,我会接受您的答案,因为它为我的问题提供了两个主要修复程序。谢谢。 – shrike

+0

@shrike是的,你以前需要在它们之间有一个空格,但是它在C++ 11中是固定的。 – TartanLlama

1

你需要告诉编译器Nested是一个模板:

template<typename A, typename B, typename C = typename A::template Nested<B>> 
struct X 
{ 
    // ... 

无论如何,由于不同的错误,您的代码将无法编译:

error: explicit specialization in non-namespace scope 'struct Asample' 
    template<> 

您需要在名称空间范围内专门设置Nested