gpt4 book ai didi

c++ - C++ 11:如何编写两个返回类型不同的模板函数

转载 作者:行者123 更新时间:2023-12-01 14:42:27 25 4
gpt4 key购买 nike

我想做的是有两个函数模板:一个将模板转换为boost::optional<some integer type>的模板,另一个将模板转换为boost::optional<some enum type>的模板。像这样:

template<typename T> boost::optional<T> func(const std::string &s) { return boost::make_optional(std::stoi(s));}
template<typename T> boost::optional<T> func(const std::string &s) { return boost::make_optional(EnumMapper<T>::map_string_to_enum<T>(s));}

enum Color { Red, Blue, Green};
enum Direction { Up, Down, Left, Right};

auto a = func<int>("1234");
auto b = func<Color>("red");
auto c = func<Direction>("up");
我在为每种枚举类型进行特化的地方工作:
template<> boost::optional<Color> func(const std::string &s) { return boost::make_optional(EnumMapper<Color>::map_string_to_enum<Color>(s));}
template<> boost::optional<Direction> func(const std::string &s) { return boost::make_optional(EnumMapper<Direction>::map_string_to_enum<Direction>(s));}
但实际上有几十个枚举,这似乎很丑陋且容易出错。我感觉这就是类型特征的用途,但是我发现的所有示例似乎都不适合我想做的事情。
编辑:感谢songyuanyao!这有效:
#include <iostream>
#include <type_traits>
#include <string>
#include <boost/optional.hpp>
#include <cstdint>

enum Color {
Red,
Green,
Blue
};

enum Direction {
Up,
Down,
Left,
Right
};

template <typename T> struct EnumMapper { static boost::optional<T> map_string_to_enum(const std::string &s) = delete; };

template <> boost::optional<Color> EnumMapper<Color>::map_string_to_enum(const std::string &s) {
return Color::Green;
}

template <> boost::optional<Direction> EnumMapper<Direction>::map_string_to_enum(const std::string &s) {
return Direction::Right;
}

template<typename T>
typename std::enable_if<std::is_enum<T>::value, boost::optional<T>>::type
func(const std::string &s) {
return EnumMapper<T>::map_string_to_enum(s);
}

template<typename T>
typename std::enable_if<std::is_integral<T>::value, boost::optional<T>>::type
func(const std::string &s) {
return boost::make_optional<T>(std::stoi(s));
}

int
main() {
auto a = func<std::uint8_t>("123");
std::cout << static_cast<int>(*a) << std::endl;
auto b = func<Color>("Red");
std::cout << static_cast<int>(*b) << std::endl;
auto c = func<Direction>("Up");
std::cout << static_cast<int>(*c) << std::endl;
auto d = func<std::uint32_t>("2345");
std::cout << static_cast<int>(*d) << std::endl;
}

最佳答案

您可以使用trait std::is_enum类型,并应用SFINAE

template<typename T>
typename std::enable_if<std::is_enum<T>::value, boost::optional<T>>::type
func(const std::string &s) {
return boost::make_optional(EnumMapper<T>::map_string_to_enum<T>(s));
}
注意,对于第一个重载,您也必须限制类型。您可以检查它是 int还是使用 std::is_integral。例如。
template<typename T>
typename std::enable_if<std::is_same<T, int>::value, boost::optional<T>>::type
func(const std::string &s) {
return boost::make_optional(std::stoi(s));
}

关于c++ - C++ 11:如何编写两个返回类型不同的模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62910702/

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