创建 std::tuple 时从 const char* 或 char* 推导 std::string

Deducing std::string from const char* or char* when creating a std::tuple

我想知道在制作元组时是否有一种简单的方法可以从 const char* 中推导出 std::string。 我自己的元组实现可以实现,但我想知道 std::tuple

是否可行

例如,在下面的代码中,storage_ 的类型为:

std::tuple<int, int, const char*>

std::tuple<const char*, char*>

我想得到:

std::tuple<int, int, std::string>

std::tuple<std::string, std::string>

#include <tuple>
#include <string>
#include <string.h>
template<typename T>
class foo
{
public:
    foo(T storage) : storage_(std::move(storage)) {}
private:
    T storage_;
};

int main()
{
    char* s2 = strdup("123");

    foo f { std::make_tuple(12,123,"1234") };

    foo f2 { std::make_tuple("321", s2) };

    free(s2);
    // still want to keep s2 stored in f2
}

我知道我可以写 std::tuple<int,std::string> t1 = std::make_tuple(123,"12"); 但这并不能解决我的问题,因为我想以任何顺序传递任意数量的参数

解法: https://wandbox.org/permlink/MsUxZ18SYD1K2ujv

不管这是否是你应该做的事情,问题仍然可以按原样回答:

我认为如果不提供您自己的 make_tuple,您将无法完成此任务。

值得庆幸的是,std::make_tuple() 仍然可以完成很多繁重的工作。实际上,您所要做的就是明确指定模板参数,而不是让它们被推导:

template<typename T>
struct Promoted {
    using type = T;
};

template<>
struct Promoted<const char *> {
    using type = std::string;
};

template<typename T>
using Promoted_t = typename Promoted<T>::type;

template<typename... ArgsT>
auto make_my_tuple(ArgsT&&... args) {
    return std::make_tuple<Promoted_t<std::decay_t<ArgsT>>...>(std::forward<ArgsT>(args)...);
}

免责声明: 我发布的代码并不是一个完整的解决方案。这是我将如何解决这个问题的指南。可能有一些边缘情况未在此处涵盖。