Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从实现者元组构造包装器元组? 我有一些实现器类(隐含)和一些用于用户的包装,在C++中实现。我想将impl和wrappers保存在两个不同的元组中,这样我就可以通过一次分配来初始化impl。(我还有其他原因:)_C++_C++11_Visual Studio 2012_Stdtuple - Fatal编程技术网

如何从实现者元组构造包装器元组? 我有一些实现器类(隐含)和一些用于用户的包装,在C++中实现。我想将impl和wrappers保存在两个不同的元组中,这样我就可以通过一次分配来初始化impl。(我还有其他原因:)

如何从实现者元组构造包装器元组? 我有一些实现器类(隐含)和一些用于用户的包装,在C++中实现。我想将impl和wrappers保存在两个不同的元组中,这样我就可以通过一次分配来初始化impl。(我还有其他原因:),c++,c++11,visual-studio-2012,stdtuple,C++,C++11,Visual Studio 2012,Stdtuple,问题是VisualStudio2012标准库的元组类不允许我在没有常量引用的包装器副本构造函数的情况下构造包装器元组。不幸的是,我需要在这种情况下进行const_cast,例如: #include <iostream> #include <type_traits> #include <tuple> #include <typeinfo> template <typename Member> struct A { A(Membe

问题是VisualStudio2012标准库的元组类不允许我在没有常量引用的包装器副本构造函数的情况下构造包装器元组。不幸的是,我需要在这种情况下进行const_cast,例如:

#include <iostream>
#include <type_traits>
#include <tuple>
#include <typeinfo>

template <typename Member>
struct A
{
    A(Member& m) : member(m)
    { std::cout << typeid(Member).name() << " MMBR " << member << std::endl; }

    A(const Member& m) : member(const_cast<Member&>(m))
    { std::cout << typeid(Member).name() << " CMBR " << member << std::endl; }

    void Print()
    {
        std::cout << typeid(Member).name() << " PRNT " << member << std::endl;
    }

    Member& member;//yes I need to hold this as a mutable reference
};

int main()
{
    typedef std::tuple<A<int>, A<double>, A<short>> WrapperTuple;
    typedef std::tuple<int, double, short> Tuple;

    Tuple t(0, 1, 2);
    WrapperTuple w(t);

    std::get<1>(w).Print();
    return std::cin.get();
}
#包括
#包括
#包括
#包括
模板
结构A
{
A(成员和m):成员(m)

{std::coutstd::tuple
的复制构造函数,甚至是转换构造函数,显然复制了所有元素,而且由于副本不应更改复制自元素,因此它们被标记为
const
。这种行为在大多数情况下是完全合理的

特例的解决方法比您喜欢的要复杂一些,但它是有效的。基本思想是,从概念上讲,您不想复制元组,但您想使用元组的元素作为其他元组元素的初始值设定项,因此它们的
常量
属性应该保留

template<unsigned...> struct seq{};
template<unsigned N, unsigned... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>{};
template<unsigned... Is>
struct gen_seq<0, Is...> : seq<Is...>{};

namespace aux{
template<class... Ts, unsigned... Is>
std::tuple<Ts&...> tie_all_(std::tuple<Ts...>& other, seq<Is...>){
  return std::tie(std::get<Is>(other)...);
}
} // aux::

template<class... Ts>
std::tuple<Ts&...> tie_all(std::tuple<Ts...>& other){
  return aux::tie_all_(other, gen_seq<sizeof...(Ts)>());
}
如果您有不同的包装器类:

template<template<class> class Wrapper, class... Ts>
std::tuple<Wrapper<Ts>...> wrap_all_in(std::tuple<Ts...>& other){
  return tie_all(other);
}
// ...
auto w = wrap_all_in<A>(t);
模板
std::tuple wrap\u all\u in(std::tuple和其他){
返回所有(其他)接头;
}
// ...
自动w=全部包裹(t);

std::tuple的复制构造函数,即使是转换构造函数,显然也会复制所有元素,而且由于副本不应更改从元素复制的元素,因此它们被标记为
常量。这种行为在大多数情况下是完全合理的

特例的解决方法比您喜欢的要复杂一些,但它是有效的。基本思想是,从概念上讲,您不想复制元组,但您想使用元组的元素作为其他元组元素的初始值设定项,因此它们的
常量
属性应该保留

template<unsigned...> struct seq{};
template<unsigned N, unsigned... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>{};
template<unsigned... Is>
struct gen_seq<0, Is...> : seq<Is...>{};

namespace aux{
template<class... Ts, unsigned... Is>
std::tuple<Ts&...> tie_all_(std::tuple<Ts...>& other, seq<Is...>){
  return std::tie(std::get<Is>(other)...);
}
} // aux::

template<class... Ts>
std::tuple<Ts&...> tie_all(std::tuple<Ts...>& other){
  return aux::tie_all_(other, gen_seq<sizeof...(Ts)>());
}
如果您有不同的包装器类:

template<template<class> class Wrapper, class... Ts>
std::tuple<Wrapper<Ts>...> wrap_all_in(std::tuple<Ts...>& other){
  return tie_all(other);
}
// ...
auto w = wrap_all_in<A>(t);
模板
std::tuple wrap\u all\u in(std::tuple和其他){
返回所有(其他)接头;
}
// ...
自动w=全部包裹(t);

为什么不创建
wrapped\u tuple
模板来包装整个
tuple
,并提供
get
的实现?保存对单个tuple元素的引用似乎是多余的,因为tuple具有固定的布局,编译器可以发出简单的代码来引用给定的单个元素对元组的引用

例如(在没有可变模板的情况下执行此操作,这有点烦人):

模板类包装的\u元组;
模板
typename std::元组元素::类型&
获取(包装的元组(&w){
返回std::get(w.tuple_);
}
模板类包装的元组{
模板
好友类型名称std::tuple\u元素::类型&
::获取(包装的元组&w);
公众:
包装的(tuple&t):tuple(t){
私人:
元组&元组;
};
模板
包装的\u元组包装的\u元组(元组和元组){
返回包装的数组(tup);
}

在ideone上。

为什么不创建
wrapped\u tuple
模板来包装整个
tuple
,并提供
get
的实现?保存对单个tuple元素的引用似乎是多余的,因为tuple有固定的布局,编译器可以发出简单的代码来引用单个元素nt提供了对元组的引用

例如(在没有可变模板的情况下执行此操作,这有点烦人):

模板类包装的\u元组;
模板
typename std::元组元素::类型&
获取(包装的元组(&w){
返回std::get(w.tuple_);
}
模板类包装的元组{
模板
好友类型名称std::tuple\u元素::类型&
::获取(包装的元组&w);
公众:
包装的(tuple&t):tuple(t){
私人:
元组&元组;
};
模板
包装的\u元组包装的\u元组(元组和元组){
返回包装的数组(tup);
}

在ideone上。

您的答案非常好,非常感谢。但是VS2012目前不支持可变模板。我已经尝试使用递归模板实现这一点两个小时了,但我失败了。如果您能帮助解决这一问题,那就太好了。@zahir:您可以下载11月的CTP,它有一个早期的imple尝试使用可变模板。递归版本将非常难看,我甚至不确定它是否能在VC11中工作。sIt将很难说服项目中的其他人安装CTP来工作,但最终您的答案将是正确的(假设MS中的VC++团队能够实现C++11一致性).另一个想法是,您的答案实际上有更广泛的用途,用于将元组元素映射到其他元素(如关系代数中的投影或linq查询的select子句)@zahir:是的,我们称之为的有很多用于扩展元组、包、数组、通用容器和其他任何东西。您的回答非常好,非常感谢。但是VS2012目前不支持可变模板。我一直在尝试使用递归模板实现这一点,大约两个小时了,但我失败了。它是如果你能帮助解决这个问题,那就太好了。@zahir:你可以下载11月的CTP,它有一个可变模板的早期实现,并尝试让它工作。递归版本会很难看,我甚至不确定它在VC11中是否能工作。sIt很难说服项目中的其他人在这是可行的,但最终你的答案是正确的(假设微软的VC++团队会提出C++11一致性)。再想想,你的答案实际上有更广泛的用途,用于将元组元素映射到其他元素(如关系代数中的投影或linq查询的select子句)@zahir:是的,我们称之为的有很多用于扩展元组、包、数组、通用容器和其他任何东西。谢谢你的回答