代码>,这是一个包含 t>代码>或 e < /c>值>的联合。,c++,c++11,templates,move-semantics,rvalue-reference,C++,C++11,Templates,Move Semantics,Rvalue Reference" /> 代码>,这是一个包含 t>代码>或 e < /c>值>的联合。,c++,c++11,templates,move-semantics,rvalue-reference,C++,C++11,Templates,Move Semantics,Rvalue Reference" />

如何重写aguments`const T&;的泛型函数及"T& ;&;`在哪里T可以作为参考? 我试图在C++中实现Rust的结果>代码>,这是一个包含 t>代码>或 e < /c>值>的联合。

如何重写aguments`const T&;的泛型函数及"T& ;&;`在哪里T可以作为参考? 我试图在C++中实现Rust的结果>代码>,这是一个包含 t>代码>或 e < /c>值>的联合。,c++,c++11,templates,move-semantics,rvalue-reference,C++,C++11,Templates,Move Semantics,Rvalue Reference,它的一些构造器是: template <typename T, typename E> Result<T,E>::Result(const T& value) : isOk(true), value(value) {} template <typename T, typename E> Result<T,E>::Result(T&& value) : isOk(true), value(std::move(value))

它的一些构造器是:

template <typename T, typename E>
Result<T,E>::Result(const T& value) : isOk(true), value(value) {}

template <typename T, typename E>
Result<T,E>::Result(T&& value) :  isOk(true), value(std::move(value)) {}
产生以下错误:

./result.h:46:5: error: multiple overloads of 'Result' instantiate to the same signature 'void (MyType &)'
    Result(T&& value);
    ^
main.cpp:39:23: note: in instantiation of template class 'Result<MyType &, int>' requested here
  Result<MyType&,int> result(object);
                      ^
./result.h:37:5: note: previous declaration is here
    Result(const T& value);
    ^
/result.h:46:5:错误:“result”的多个重载实例化为同一签名“void(MyType&)”
结果(T&值);
^
main.cpp:39:23:注意:在这里请求的模板类“Result”的实例化中
结果(对象);
^
/结果.h:37:5:注:此处为先前声明
结果(常数T和值);
^
我理解这是因为引用折叠规则(&+&&&&&):如果
T
MyType&
,那么
T&
T&&
都是
MyType&
,因此这两个构造函数在这里具有相同的签名


但是有什么好方法可以克服这一点,允许
T
作为引用,同时仍然有
const T&
T&
构造函数?

您可以使用带有转发引用的模板构造函数来覆盖这两种情况:

template<typename T>
struct Result {
    template<typename... S>
    Result(S&&... s) : t(std::forward<S>(s)...) {}

    T t;
};

int i;
Result<int&> r1(i);
Result<int> r2(i);
模板
结构结果{
模板
结果(S&&…S):t(std::forward(S)…{}
T;
};
int i;
结果r1(i);
结果r2(i);
关于
std::预期
提案的相关论文:


您希望
Result
存储引用,还是希望它有自己的对象?您希望
Result
存储什么数据,以及希望它有什么构造函数?@NathanOliver,@n.m.,如果
T
是引用(如
MyType&
),则我希望它存储引用,否则,它应该通过移动或复制来创建它自己的对象。因此,为了涵盖
T
vs
E
@Jarod42,它不应该是区分构造函数的标记吗?如果
T
E
是同一类型怎么办?@AndriiZymohliad,它是一个参数包,这样你就可以用任意数量的参数编写
结果(a,b,c,…)
,并将它们全部传递给
T
的构造函数:
T(a,b,c,…)
。要将引用放入联合体中,您可以使用
std::reference\u wrapper
:@AndriiZymohliad,一个可能的解决方案是使它始终包含非引用,然后如果有人想将引用放入
Result
,他自己使用
std::reference\u wrapper
。@AndriiZymohliad,还可以看看这篇文章:
template<typename T>
struct Result {
    template<typename... S>
    Result(S&&... s) : t(std::forward<S>(s)...) {}

    T t;
};

int i;
Result<int&> r1(i);
Result<int> r2(i);