gpt4 book ai didi

c++ - 获取具有通用返回类型的函数

转载 作者:行者123 更新时间:2023-11-28 01:55:53 27 4
gpt4 key购买 nike

我尝试实现一个包含多个名称-值对的数据结构,其中值的类型可能不同:

template< typename T >
struct name_value_pair
{
std::string name;
T value;
};


template< typename... Ts >
class tuple_of_name_value_pairs
{
public:
/* type of value */ get_value( std::string n )
{
// return the value that the element in
// _name_value_pairs with name "n" comprises
}

private:
std::tuple<Ts...> _name_value_pairs:
};

不幸的是,我不知道如何实现get 函数。

解决方法是将名称声明为 integer 而不是 string 并根据 std::get 使用实现,但这这里没有选项:get 的输入类型必须是字符串。

有人有想法吗?

最佳答案

首先请记住,您不能直接做您想做的事。 C++ 是一种强类型语言,因此必须编译时知道函数结果的类型。因此,当然,如果您传递给 getter 的字符串在运行时已知,您将无法在编译时分派(dispatch)函数以让编译器推断出适当的结果类型。但是当您接受需要类型删除来删除 getter 结果类型时,您可以使用例如boost::variant 来处理你的问题。 C++14 示例(使用 boost,因为 c++17 变体应该在 std 中可用):

#include <boost/variant.hpp>
#include <utility>
#include <iostream>
#include <tuple>

template< typename T >
struct name_value_pair
{
using type = T;
std::string name;
T value;
};

template <std::size_t N, class = std::make_index_sequence<N>>
struct getter;

template <std::size_t N, std::size_t... Is>
struct getter<N, std::index_sequence<Is...>> {
template <class Val, class Res>
void setRes(Val &val, Res &res, std::string &s) {
if (val.name == s)
res = val.value;
}

template <class Tup>
auto operator()(Tup &tuple_vals, std::string &s) {
boost::variant<typename std::tuple_element<Is, Tup>::type::type...> result;
int helper[] = { (setRes(std::get<Is>(tuple_vals), result, s), 1)... };
(void)helper;
return result;
}
};

template <std::size_t N, class = std::make_index_sequence<N>>
struct setter;

template <std::size_t N, std::size_t... Is>
struct setter<N, std::index_sequence<Is...>> {
template <class Val, class SVal>
std::enable_if_t<!std::is_same<SVal, typename Val::type>::value> setVal(Val &, std::string &, const SVal &) { }
template <class Val>
void setVal(Val &val, std::string &s, const typename Val::type &sval) {
if (val.name == s)
val.value = sval;
}

template <class Tup, class Val>
auto operator()(Tup &tuple_vals, std::string &s, const Val &val) {
int helper[] = { (setVal(std::get<Is>(tuple_vals), s, val), 1)... };
(void)helper;
}
};

template <class T, class Res>
using typer = Res;

template< typename... Ts >
class tuple_of_name_value_pairs
{
public:
auto get_value( std::string n )
{
return getter<sizeof...(Ts)>{}(_name_value_pairs, n);
}
template <class T>
void set_value( std::string n, const T& value) {
setter<sizeof...(Ts)>{}(_name_value_pairs, n , value);
}
void set_names(typer<Ts, std::string>... names) {
_name_value_pairs = std::make_tuple(name_value_pair<Ts>{names, Ts{}}...);
}

private:
std::tuple<name_value_pair<Ts>...> _name_value_pairs;
};

int main() {
tuple_of_name_value_pairs<int, float, double> t;
t.set_names("abc", "def", "ghi");
t.set_value("abc", 1);
t.set_value("def", 4.5f);
t.set_value("ghi", 5.0);

std::cout << t.get_value("def") << std::endl;
}

[live demo]

我相信您将能够优化代码(例如,利用移动语义/完美转发等)。这只是向您介绍如何开始实现。

关于c++ - 获取具有通用返回类型的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41197882/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com