为什么模板化类的模板化typef是无效语法
Why is a templated typef of a templated class invalid syntax?
使用MSVC12,我在尝试typedef
一个依赖的类型名时遇到了一个奇怪的语法错误,比如:
template <typename ... LeftT>
struct A{
template <typename ...>
struct B{};
template <typename T, typename ... RightT>
struct B <T, RightT ... >{
typedef typename A<LeftT ..., T> nextA;
typedef typename nextA::B<RightT ...> nextB; //error C2059: syntax error : '<'
};
};
这就是它的一切,模板除了在自己内部之外从未被实例化。
我的问题:为什么我在这里遇到语法错误?这不是有效的语法吗
你可能会问:你为什么要这么做?
基本思想是通过类型转换进行转发。这将通过专门化B
来实现,从而使T
具有某种类型,然后可以对其进行转换。下面将详细解释它的工作原理,包括完整的代码片段。
如果这个问题措辞不好或难以理解,请帮助我改进。这是我一直在研究的最复杂的模板问题之一。英语不是我的母语。
为什么疯狂
作为一个练习,我想编写一个模板构造,使我能够调用printf
和类似的函数,这些函数需要char[]
s和std::string
s。
为此,我必须遍历每一个参数,并专门研究它可能是std::string
的情况。为了做到这一点,我有一个结构fwd<typename func_t, typename ... LeftArgs>
,它包含所有已处理的参数,在它内部有一个one_arg<typename Arg, typename ... RightArgs>
,它允许通过专门处理空的基本情况和Arg
是std::string
的情况来处理当前参数。基本情况(没有参数,或者没有剩余的处理)是这样处理的:
template<typename ...>
struct one_arg
{
//implementation of return_type will be shown below
static return_type forward(func_t func, LeftArgs ... leftArgs){
return func(leftArgs ...); //execute function
}
};
专门化基本情况是一个参数具有除std::string
:之外的任何类型的常见情况
template<typename Arg, typename ... RightArgs>
struct one_arg < Arg, RightArgs ...>
{
//move Arg to the processed arguments
typedef typename fwd< func_t, LeftArgs..., Arg>::one_arg<RightArgs...> next_arg;
static return_type forward(func_t func, LeftArgs ... leftArgs, Arg arg, RightArgs ... rightArgs){
return next_arg::forward(func, leftArgs ..., arg, rightArgs ...);
}
};
使用几乎相同的语法,更进一步地专门化了这种常见的情况,即当前参数的类型确实是std::string
:
template<typename ... RightArgs>
struct one_arg < std::string, RightArgs ...>
{
//again, move Arg to the processed arguments, but as a char[]
typedef typename fwd< func_t, LeftArgs..., char[]>::one_arg<RightArgs...> next_arg;
static return_type forward(func_t func, LeftArgs ... leftArgs, std::string arg, RightArgs ... rightArgs){
//convert string to char[]
return next_arg::forward(func, leftArgs ..., arg.c_str(), rightArgs ...);
}
};
我希望结构是显而易见的。如果没有,这里是整个片段,准备好了。
完整片段:
#include <string>
using namespace std;
//get the return type of a function
template <typename T>
struct get_return_type;
template <typename R, typename ... A>
struct get_return_type<R(A...,...)>
{
typedef R type;
};
template<typename func_t, typename ... LeftArgs>
struct fwd{
typedef typename get_return_type<func_t> return_type;
//empty base case
template<typename ...>
struct one_arg
{
static return_type forward(func_t func, LeftArgs ... leftArgs){
return func(leftArgs ...);
}
};
//normal forwarding
template<typename Arg, typename ... RightArgs>
struct one_arg < Arg, RightArgs ...>
{
typedef typename fwd< func_t, LeftArgs..., Arg>::one_arg<RightArgs...> next_arg;
static get_return_type<func_t> forward(func_t func, LeftArgs ... leftArgs, Arg arg, RightArgs ... rightArgs){
return next_arg::forward(func, leftArgs ..., arg, rightArgs ...);
}
};
//specialisation for std::string
template<typename ... RightArgs>
struct one_arg < std::string, RightArgs ...>
{
typedef typename fwd< func_t, LeftArgs..., char[]>::one_arg<RightArgs...> next_arg;
static get_return_type<func_t> forward(func_t func, LeftArgs ... leftArgs, std::string arg, RightArgs ... rightArgs){
return next_arg::forward(func, leftArgs ..., arg.c_str(), rightArgs ...);
}
};
};
template<typename func_t, typename ... Args>
typename fwd<func_t>::one_arg<Args ...>::return_type forward_stoc(func_t func, Args ... args){
typedef typename fwd<func_t>::one_arg<Args ...> next_arg;
return next_arg::forward(func, args...);
}
nextA
是一个依赖范围,因此需要指出B
是模板的名称:
typedef typename nextA::template B<RightT ...> nextB;
^^^^^^^^
注意,在nextA
的声明中不应该有typename
,因为不涉及依赖范围:
typedef A<LeftT ..., T> nextA;
有关血腥的细节,请参阅"我必须在哪里以及为什么要放";模板";以及";typename";关键词?
- 1d 智能指针不适用于语法 (*)++
- 助记符和指向成员语法的指针
- 有人能分解一下这个c++模板的语法吗
- C++避免重复声明的语法是什么
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 无法访问嵌套类.类的使用无效
- QMetaObject invokeMethod的基于函数指针的语法
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 如果用户输入无效,如何使用字符串变量-C++重复输入命令
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 如何解决错误:SCIP C++中的 SCIP 阶段无效 <10>
- 在没有参数列表的情况下使用模板名称"Event"无效,模板问题
- FFMPEG配置文件级别id大小无效
- 无效删除运算符语法
- 获取错误makefile:45:条件中的语法无效.停止
- 未知语法无效(类型::m_function)()
- 如何处理传递给构造函数的语法有效但逻辑无效的参数
- 为什么模板化类的模板化typef是无效语法
- int a[]{(functioncall(a1,a2),0)..};(无效(a));这个语法是什么意思
- Unordered_map - {{key,value},{key,value}}语法无效