我正在编写一个负责格式化和打印信息的方法。
boost::optional<T>
中存在问题/功能,will print an extra blank space将optional
输出到流时,当且仅当boost::optional<T>
具有值时才会显示。
我可以看到两个选项:
boost::optional<T>
template <typename T>
void print(const T& o)
{
std::cout << o << "\n";
}
template <typename T>
void print_optional(const boost::optional<T>& o)
{
if (o)
print(*o);
else
print("--");
}
类型并相应处理选项1 可能是这样的:
print()
它有效,但是如果我们使用boost::optional
调用static_assert
,则会出现无编译错误的问题。我知道std::is_type
和boost::optional
,,但由于boost::optional<T>
本身是模板化的,我不知道如何检查它。
选项2 对我来说非常理想,但问题仍然存在:如何询问代码变量是HashSet<T>
而不管T? < / p>
答案 0 :(得分:5)
你可以重载print
函数:
template <typename T>
void print(const T& o)
{
std::cout << o << "\n";
}
template <typename T>
void print(const boost::optional<T>& o)
{
if (o)
print(*o);
else
print("--");
}
如果您传递boost::optional
,则会正确选择第二次重载,否则会发生第一次重载。
答案 1 :(得分:3)
正如其他答案所说,模板过载应该解决了你的问题;只是直接回答您的问题,您可以通过具有部分特化的类模板检查类型是否是boost::optional
的实例化,例如
template <typename>
struct is_optional : std::false_type {};
template <typename T>
struct is_optional<boost::optional<T>> : std::true_type {};
template <typename T>
void print(const T& o)
{
static_assert(!is_optional<T>::value, "Please use print_optional instead.");
std::cout << o << "\n";
}
答案 2 :(得分:1)
只是重载print
:
template <typename T>
void print(const T& o)
{
std::cout << o << "\n";
}
template <typename T>
void print(const boost::optional<T>& o)
{
if (o)
print(*o);
else
print("--");
}
答案 3 :(得分:0)
添加以前任何答案都没有提供的解决方案:
您可以使用带有模板特化的结构来检查类型是否为optional
,如下所示:
template < typename >
struct is_optional : std::false_type {};
template < typename T >
struct is_optional<std::optional<T>> : std::true_type {};
现在,您可以使用std::enable_if_t
来设置一个对optional<T>
输入和其他输入采取不同行为的方法:
template < typename T >
std::enable_if_t<!is_optional<T>::value, void> print(const T& o)
{
std::cout << o << "\n";
}
template < typename T >
std::enable_if_t<is_optional<T>::value, void> print(const T& o)
{
if (o)
print(*o);
else
print("--");
}
注意:为optional<T>
显式重载方法是一个更好的解决方案,因为它更干净,更易读并且不需要is_optional
结构,但这是尽管如此,这是一个有效的实施方案。