我正在尝试制作自己的 tuple
实现以供练习。我试图将 std::string
作为 rvalue
传递到我的元组中。但是,我无法编译代码,想知道如何解决这个问题。我知道它会衰减为 char * const
,并将其代入我的模板参数中是可行的,但是当尝试使用标准库版本的 std::make_tuple(Args&&... )
右值引用
没有问题。所以我很好奇我在实现中遗漏了什么以及如何修复它。深入理解的详细解释将不胜感激。
主要.cpp
int main()
{
//Tuple<int, int> int_tuple = custom_make_tuple(1, 2);
int a = 1;
int b = 1;
std::string Testing = "testing";
Tuple<int, int, char, std::string> t1 = makeTuple(1, b, 'c', "test"); //Fails to compile
Tuple<int, int, char, std::string> t1 = makeTuple(1, b, 'c', Testing); //OK
std::tuple<std::string> test = std::make_tuple("test"); //OK
return 0;
}
元组.h
template<typename... Types>
class Tuple;
// recursive case:
template<typename Head, typename... Tail>
class Tuple<Head, Tail...>
{
private:
Head head;
Tuple<Tail...> tail;
public:
constexpr Tuple() {
}
template<typename FHead, typename... FTail>
constexpr Tuple(FHead && head, FTail &&... tail)
: head(std::forward<FHead>(head)), tail(std::forward<FTail>(tail)...) {}
constexpr Head& GetHead() { return head; }
constexpr Head const& GetHead() const { return head; }
constexpr Tuple<Tail...>& GetTail() { return tail; }
constexpr Tuple<Tail...> const& GetTail() const { return tail; }
};
// basis case:
template<>
class Tuple<> {};
template<typename... Eles>
constexpr auto makeTuple(Eles&&... elems)
{
return Tuple<std::decay_t<Eles>...>(std::forward<Eles>(elems)...);
}
最佳答案
makeTuple(1, b, 'c', "test")
返回 Tuple<int, int, char, const char*>
.然后你尝试复制构建一个 Tuple<int, int, char, std::string>
从那个元组,这是行不通的,因为 Tuple<int, int, char, std::string>
的构造函数需要类型为 int
的参数, int
, char
, 和 std::string
, 不是 Tuple<int, int, char, const char*>
.
您需要添加转换构造函数来接受元组并将包含的对象转换为您需要的类型:
template <typename... Types>
friend class Tuple;
template<typename FHead, typename... FTail,
std::enable_if_t<sizeof...(Tail) + 1 == sizeof...(FTail) + 1>* = nullptr>
constexpr Tuple(const Tuple<FHead, FTail...>& o)
: head(o.head), tail(o.tail)
{}
template<typename FHead, typename... FTail,
std::enable_if_t<sizeof...(Tail) + 1 == sizeof...(FTail) + 1>* = nullptr>
constexpr Tuple(Tuple<FHead, FTail...>&& o)
: head(std::move(o.head)), tail(std::move(o.tail))
{}
请注意 std::enable_if_t
存在参数是为了避免在您实际尝试创建 Tuple
时选择转换构造函数包含单个 Tuple
.
关于c++ - std::make_tuple 是右值引用时如何保留 std::string 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49419611/