Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++ 推断类型,同时省略没有宏的移动/复制_C++_Templates_Constructor_C++11 - Fatal编程技术网

C++ 推断类型,同时省略没有宏的移动/复制

C++ 推断类型,同时省略没有宏的移动/复制,c++,templates,constructor,c++11,C++,Templates,Constructor,C++11,考虑以下简单的make_pair类: template <class X, class Y> struct Pair { X x; Y y; }; 然后我们可以做: auto z2 = make_pair(C(3),C(4)); auto z3 = MAKE_PAIR(C(5),C(6)); 但这表明: Move: 3 Move: 4 如果C是堆分配的类型,那么这不是问题,但是如果是堆栈分配的类型,那么移动基本上就是复制 然后让我们定义这个宏: #define

考虑以下简单的
make_pair
类:

template <class X, class Y>
struct Pair
{
    X x;
    Y y;
};
然后我们可以做:

auto z2 = make_pair(C(3),C(4));
auto z3 = MAKE_PAIR(C(5),C(6));
但这表明:

Move: 3
Move: 4
如果
C
是堆分配的类型,那么这不是问题,但是如果是堆栈分配的类型,那么移动基本上就是复制

然后让我们定义这个宏:

#define MAKE_PAIR(x,y) decltype(make_pair(x,y)){x,y}
然后我们可以做:

auto z2 = make_pair(C(3),C(4));
auto z3 = MAKE_PAIR(C(5),C(6));
这可以进行类型推断,不需要移动。但我们需要制作一个宏,我觉得这有点混乱,也阻止了我们使用操作符来做这类事情

是否有一种解决方案可以执行以下操作:

(1) 推断类型(如2和3)
(2) 不需要复制或移动(如1和3)
(3) 不需要宏(如1和2)

我能得到的最好结果是三分之二,但三分之三肯定是可能的吗?我无法想象C++会强迫一个宏使用我的行为,因为C++显然正在远离宏。 代码是

<> P>我无法想象C++会强迫一个宏使用我的行为,因为C++显然正在远离宏。 你追求的行为从一开始就没有得到标准的保证。省略是一种优化;任何实施都不需要它。所以他们中没有一个能保证做你想做的事,尽管很明显,他们中的一些人至少让这成为可能

有效地转发使省略变得不可能;对于这个事实,我们无能为力。完美的转发是关于引用和引用崩溃的;elision是关于初始化值参数的值,它在初始调用站点不知道这些值

在现实世界中,这不应该是一个问题。事实上,大多数值得忽略的东西都是复制成本很高的东西。复制一些
int
s或
浮动
,特别是对于一个普通类,甚至可能不会在探查器上显示为一个光点。在绝大多数情况下,复制成本很高的对象之所以如此,是因为它们拥有某种资源,例如分配的内存。因此,大多数复制成本较高的类型也可以移动,因此移动成本较低


在任何情况下,是的,如果您希望有省略的可能性,您不能使用转发。

在您的示例中,您仍然需要指定一次类型。如果您的目标是避免多次指定类型,则可以执行以下操作:

auto z = Pair<C,C>{3,4};
auto z=Pair{3,4};
请注意,如果您有更复杂的构造函数,这甚至可以工作:

struct C {
  C(int,int) { }
  C(int) { }
};

auto z = Pair<C,C>{{1,2},3};
struct C{
C(int,int){}
C(int){}
};
自动z=对{1,2},3};

并且不需要拷贝。

,不确定移动。(注意:如果传递左值,您的
make_pair
将创建一个
pair
。)因此,没有副本。)如果基于堆栈的类太大,这是一个问题,那么您就做错了。@Xeo:Hehe,我想知道这是出于设计还是我应该说些什么。在maker函数中,有一点
remove\u reference
decay
很可能是有序的。@KerrekSB,Xeo:这不是特别设计的,但不是主要考虑的问题。我想说的主要问题是,临时机构应该建立在适当的位置。它们在示例(1)和(3)中,但不在(2)中。当要求我的编译器进行优化时,当特殊成员的输出仍在执行时,所有对
C
Pair
make\u Pair
的引用都会被删除。因此,可以肯定的是,复制品并没有因为其副作用得以保留而被忽略。但无论如何,这些对象都不在这里。考虑到副作用被放在这里大概是为了仪器,那么我真的不知道问题是关于什么的。
struct C {
  C(int,int) { }
  C(int) { }
};

auto z = Pair<C,C>{{1,2},3};