我有以下模板类&样本类:
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"; }
};
使用vc14时,上面的代码编译得很好,并为X<Asample, Bsample>
默认模板参数C
到Asample::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
,template
来声明模板参数typename
的默认值,但是没有成功使用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 :(得分:4)
您需要typename
和 template
:
template<typename A, typename B, typename C = typename A::template Nested<B>>
template
表示A::Nested
是一个模板,而typename
表示A::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>"; }
};
答案 1 :(得分: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
。