检测模板类型本身是模板类型

时间:2017-10-11 09:08:59

标签: c++ templates boost types

我正在编写一个负责格式化和打印信息的方法。

boost::optional<T>中存在问题/功能,will print an extra blank spaceoptional输出到流时,当且仅当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_typeboost::optional,但由于boost::optional<T>本身是模板化的,我不知道如何检查它。

选项2 对我来说非常理想,但问题仍然存在:如何询问代码变量是HashSet<T>而不管T? < / p>

4 个答案:

答案 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,则会正确选择第二次重载,否则会发生第一次重载。

Live demo

答案 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结构,但这是尽管如此,这是一个有效的实施方案。