C++ 有没有可能;商店「;没有展开的模板参数包?
我在试验C++0x可变模板时偶然发现了这个问题:C++ 有没有可能;商店「;没有展开的模板参数包?,c++,templates,c++11,variadic-templates,C++,Templates,C++11,Variadic Templates,我在试验C++0x可变模板时偶然发现了这个问题: template < typename ...Args > struct identities { typedef Args type; //compile error: "parameter packs not expanded with '...' }; //The following code just shows an example of potential use, but has no relation //w
template < typename ...Args >
struct identities
{
typedef Args type; //compile error: "parameter packs not expanded with '...'
};
//The following code just shows an example of potential use, but has no relation
//with what I am actually trying to achieve.
template < typename T >
struct convert_in_tuple
{
typedef std::tuple< typename T::type... > type;
};
typedef convert_in_tuple< identities< int, float > >::type int_float_tuple;
模板
结构标识
{
typedef Args type;//编译错误:“参数包未用“…”展开”
};
//下面的代码只是显示了一个潜在用途的示例,但没有关系
//用我真正想要达到的。
模板
结构转换\u在\u元组中
{
typedef std::tupletype;
};
typedef convert_in_tuple>::键入int_float_tuple;
GCC 4.5.0在我尝试键入模板参数包时出错
基本上,我想“存储”“参数打包在typedef中,而不进行解压缩。可能吗?如果不允许,有什么原因不允许这样做吗?我认为不允许这样做的原因是这样会很混乱,你可以解决这个问题。您需要使用依赖项反转,并使将参数包存储到工厂模板中的结构能够将该参数包应用到另一个模板 大致如下:
template < typename ...Args >
struct identities
{
template < template<typename ...> class T >
struct apply
{
typedef T<Args...> type;
};
};
template < template<template<typename ...> class> class T >
struct convert_in_tuple
{
typedef typename T<std::tuple>::type type;
};
typedef convert_in_tuple< identities< int, float >::apply >::type int_float_tuple;
模板
结构标识
{
模板<模板类T>
结构应用
{
T型;
};
};
模板<模板类T>
结构转换\u在\u元组中
{
typedef typename T::type类型;
};
typedef convert_in_tuple::apply>::type int_float_tuple;
另一种方法比Ben的方法更通用,如下所示:
#include <tuple>
template <typename... Args>
struct variadic_typedef
{
// this single type represents a collection of types,
// as the template arguments it took to define it
};
template <typename... Args>
struct convert_in_tuple
{
// base case, nothing special,
// just use the arguments directly
// however they need to be used
typedef std::tuple<Args...> type;
};
template <typename... Args>
struct convert_in_tuple<variadic_typedef<Args...>>
{
// expand the variadic_typedef back into
// its arguments, via specialization
// (doesn't rely on functionality to be provided
// by the variadic_typedef struct itself, generic)
typedef typename convert_in_tuple<Args...>::type type;
};
typedef variadic_typedef<int, float> myTypes;
typedef convert_in_tuple<myTypes>::type int_float_tuple;
int main()
{}
#包括
模板
结构变量类型定义
{
//此单一类型表示类型的集合,
//作为模板参数,它需要定义它
};
模板
结构转换\u在\u元组中
{
//基本情况,没什么特别的,
//直接使用参数即可
//然而,它们需要被使用
typedef std::元组类型;
};
模板
结构转换\u在\u元组中
{
//将变量_typedef展开回
//它的论点,通过专门化
//(不依赖于要提供的功能
//通过变量(类型定义结构本身,通用)
typedef typename convert_in_tuple::type type;
};
typedef可变_typedef myTypes;
typedef convert_in_tuple::type int_float_tuple;
int main()
{}
这是GManNickG巧妙的部分专门化技巧的一个变种。无委托,通过要求使用variadic_typedef结构,您可以获得更大的类型安全性
#include <tuple>
template<typename... Args>
struct variadic_typedef {};
template<typename... Args>
struct convert_in_tuple {
//Leaving this empty will cause the compiler
//to complain if you try to access a "type" member.
//You may also be able to do something like:
//static_assert(std::is_same<>::value, "blah")
//if you know something about the types.
};
template<typename... Args>
struct convert_in_tuple< variadic_typedef<Args...> > {
//use Args normally
typedef std::tuple<Args...> type;
};
typedef variadic_typedef<int, float> myTypes;
typedef convert_in_tuple<myTypes>::type int_float_tuple; //compiles
//typedef convert_in_tuple<int, float>::type int_float_tuple; //doesn't compile
int main() {}
#包括
模板
结构变量_typedef{};
模板
结构转换\u在\u元组中{
//将此项保留为空将导致编译器失败
//试图访问“类型”成员时投诉。
//您还可以执行以下操作:
//静态断言(std::is_same::value,“blah”)
//如果你对这些类型有所了解。
};
模板
元组中的结构转换{
//正常使用Args
typedef std::元组类型;
};
typedef可变_typedef myTypes;
typedef convert_in_tuple::type int_float_tuple//汇编
//typedef convert_in_tuple::type int_float_tuple//不编译
int main(){}
我发现本·沃伊特的想法对我自己的努力非常有用。我对它进行了轻微的修改,使其不只是元组。对于这里的读者来说,这可能是一个明显的修改,但可能值得展示:
template <template <class ... Args> class T, class ... Args>
struct TypeWithList
{
typedef T<Args...> type;
};
template <template <class ... Args> class T, class ... Args>
struct TypeWithList<T, VariadicTypedef<Args...>>
{
typedef typename TypeWithList<T, Args...>::type type;
};
模板
结构类型列表
{
T型;
};
模板
结构类型列表
{
typedef typename TypeWithList::type type类型;
};
TypeWithList的名称源于这样一个事实,即该类型现在是用以前的列表实例化的 我在GCC4.5上尝试了你的代码,你只需要在
class T
中更改typename T
,并将convert\u in\u tuple
参数更改为模板参数:templateclass>class T>struct convert_in_tuple{…}
(!)。@Luc:已编辑为模板参数。将typename
替换为class
感觉有点可疑,因为草案说“在模板参数中class
和template
之间没有语义上的区别”。你能试试这个新代码吗?我在标准中找不到它,但是我想我记得,对于模板参数,你需要使用class
而不是typename
(因为模板类型不可避免地是一个类而不是任何类型)。@Luc:gcc 4.5.2在虚拟机中编译了它,谢谢你的指针。现在正在努力让VM的复制+粘贴功能正常工作……事实上,标准在§14.1.2中说,class
和typename
之间没有区别,但就在上面(在§14.1.1中),语法只允许模板参数声明中的class
关键字。尽管这看起来不一致,但我认为其基本原理是,正如我之前所说,模板参数不能是任何类型(例如,它不能是int
或bool
),因此委员会可能认为使用typename
会产生误导。不管怎样,让我们回到主题:)!非常好的解决方法,我没有考虑使用部分模板专门化@GMan:快速提问。。。这是有帮助的,但是部分专用的版本实际上应该是typedef typename convert_in_tuple::type代码>,还是没关系?@Jason:没错。我很惊讶我的答案能在这么长时间内都没有被敏锐的目光注意到我有点担心:虽然说“将类型列表或包含列表的特定类型的实例视为同一事物”很有诱惑力,但根据我的经验,当你这样做时,事情往往会变得一团糟。例如,想象一个长度为1的列表,其中包含一个可变的_typedef
,以及它如何与上述代码交互。现在想象一个类型列表,每个类型都被传递到一个convert\u-in\u元组中
,以及它如何与上面的c进行交互