此代码编译时没有任何警告或错误,并且可执行。
template<class T>
struct testclass
{
template<int I>
class inner {};
template<int I>
void f(inner<I> ) {}
};
int main()
{
testclass<bool> test;
test.f(testclass<bool>::inner<3>()); // l. 13
return 0;
}
现在,我想要做的是省略第13行中的testclass::
:
test.f(inner<3>());
它不起作用。我可以在testclass
'定义中添加任何内容,以便我的代码可以使用吗?
允许使用C ++ 11。
答案 0 :(得分:7)
一般情况下,没有全局编译器标志可以允许这样的推论,因为这会破坏名称范围。
但是,您可以在外部使用typedef(或者在模板的情况下 - 具有类型别名)。在你的情况下,它将是:
template <int I> using inner = testclass::inner<I>;
这必须用全局命名空间编写,而不是testclass
。
请注意,模板别名是 C ++ 11的一项功能
答案 1 :(得分:3)
首先,样板。
索引样板:
template<unsigned... Is> struct indexes {typedef indexes<Is...> type;};
template<unsigned Max, unsigned... Is> struct make_indexes:make_indexes<Max-1, Max-1, Is...> {};
template<unsigned... Is> struct make_indexes<0, Is...>:indexes<Is...> {};
一个助手类,允许代理构造而不命名封闭类:
template<int I, typename... Args>
struct inner_helper {
std::tuple<Args...> args;
template<typename T, unsigned... Is>
T construct(indexes<Is...>) && {
return { std::forward<Args>(std::get<Is>(args))... };
}
template<typename T>
T construct() && {
return std::move(*this).template construct<T>( make_indexes<sizeof...(Args)>() );
}
};
帮助函数,为您提供所需的语法。请注意,inner<3>
现在是一个函数调用,而不是在封闭类范围之外创建一个对象:
template<int I, typename... Args>
inner_helper<I, Args...> inner( Args&&... args ) {
return {std::forward<Args>(args)...};
}
我们用两个重载来增加testclass
。一个人使用inner_helper<int, Args...>
并使用inner<int>
构建Args...
,另一个使用inner<int>
:
template<class T>
struct testclass
{
template<int I>
class inner {};
template<int I>
void f(inner<I> ) {}
template<int I, typename... Args>
void f(inner_helper<I, Args...> h) {
return f( std::move(h).template construct<inner<I>>() );
}
};
最后,在使用时请求的语法:
int main()
{
testclass<bool> test;
test.f(inner<3>()); // l. 13
return 0;
}
这使您可以执行所需的语法(inner<3>()
),支持使用任意参数(完美转发)构造所述inner<3>
,并调用实际的f(inner<I>)
方法。 / p>
它确实要求inner<I>
可以移动构造,并且可以从inner<I>
的参数隐式构造。
我假设inner<I>
比你上面使用的类型复杂一点。如果它不复杂,你应该考虑C ++迭代器的SCARY技术,其中迭代器(内部类型sortof)实际上是外部类型。
答案 2 :(得分:2)
您不能省略testclass::
,因为inner
是testclass类的内部类。
您可以做的是更改f
功能的签名,使其更简单:
struct testclass
{
template<int I>
class inner {};
template<int I>
void f1() {
inner<I> obj;
}
template<typename T>
void f2( T&& )
{
}
};
int main()
{
testclass test;
test.f1<3>();
test.f2(testclass::inner<3>());
}