iav*_*avr 5 c++ templates namespaces forward-declaration
我在嵌套命名空间中有一个模板类的前向声明
namespace n1
{
namespace n2
{
template <typename T, typename S>
struct A;
}
using n2::A;
}
Run Code Online (Sandbox Code Playgroud)
后跟一个定义,实际上是在一个不同的文件中,其间有东西:
struct X { };
namespace n1
{
namespace n2
{
template <typename T, typename S = X>
struct A { };
}
using n2::A;
}
Run Code Online (Sandbox Code Playgroud)
然后以下总是好的:
n1::n2::A <int> a;
Run Code Online (Sandbox Code Playgroud)
但这个捷径
n1::A <int> a;
Run Code Online (Sandbox Code Playgroud)
在clang中给出编译错误
error: too few template arguments for class template 'A'
Run Code Online (Sandbox Code Playgroud)
除非我删除了前瞻性声明; g ++接受两者.
clang似乎与第一个不包含默认模板参数的声明一致(我不能包含它,因为我还没有定义X).
如果我使用单个命名空间没有问题(但这不是一个解决方案).
我做错了什么,或者哪个编译器是正确的?快捷方式如何与前向声明和嵌套命名空间一起工作?我需要他们所有人.
XS的前向声明+默认参数当然有效,但实际上太繁琐(实际上有几十个,整个文件结构都会改变).
我发现这是一个最方便的解决方法:
namespace n1
{
namespace n2
{
template <typename T, typename S>
struct A;
}
namespace fwd { using n2::A; }
}
// stuff on n1::fwd::A;
struct X { };
namespace n1
{
namespace n2
{
template <typename T, typename S = X>
struct A { };
}
using n2::A;
}
Run Code Online (Sandbox Code Playgroud)
也就是说,将第一个 using 声明移动到另一个名称空间。现在“东西”可以是这样的:
namespace n1
{
namespace stuff
{
using namespace fwd;
template <typename T>
struct R /*...*/;
template <typename T, typename S>
struct R <A <T, S> > /*...*/;
}
}
Run Code Online (Sandbox Code Playgroud)
使用A没有任何名称空间。我的项目中只有一个n1,但有很多n2,因此将所有 using 声明移到单个命名空间中n1::fwd会更方便,因为我不能只使用n1.