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

时间:2019-05-22 23:54:01

标签: c++ templates template-meta-programming stdtuple type-deduction

我想知道在创建元组时是否有一种简便的方法可以从std::string推论const char*。 我自己的元组实现可以做到这一点,但我想知道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

1 个答案:

答案 0 :(得分:2)

无论您是否应该执行此操作,仍然可以按要求回答问题:

我认为如果不提供自己的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)...);
}

免责声明:我发布的代码并不是完整的解决方案。这是我如何解决此问题的指南。可能有些边缘情况在这里没有涉及。