BOOST_STRONG_TYPEDEF几乎,但不完全像它的基础

时间:2015-02-26 14:26:04

标签: c++ c++11

我希望这个模板化代码能够用于std :: string,std :: string的BOOST_STRONG_TYPEDEF和std :: vector。

#include <boost/strong_typedef.hpp>
#include <string>
#include <vector>
#include <iostream>
BOOST_STRONG_TYPEDEF(std::string, number_value)

template <typename T>
void say(T const& v)
{
    if (v.empty()) { // doesn't work for number_value
        return; // cool, nothing to do!
    }
    if (static_cast<std::string>(v).empty()) { // doesn't work for vector
        return; // cool, nothing to do!
    }

    std::cout << v.size() << "\n";
}

int main()
{
    std::string s;
    number_value n;
    std::vector<std::string> strings;

    say(s);
    say(n);
    say(strings);
}

BOOST_STRONG_TYPEDEF(T,D)主要是

struct D {
    T t;
};

和一堆构造函数,转换和比较运算符使D看起来像T。

不幸的是,我找不到透明地访问number_value上的std :: string方法的方法,这几乎与但不完全不同于std :: string类型。

我试图隐藏一些中间函数背后的大小调用:

template <typename T>
size_t get_size(T const& v)
{
    return v.size();
}

template <typename T>
typename std::enable_if<std::is_convertible<T, std::string>::value, size_t>::type get_size(T const& v)
{
    return static_cast<std::string>(v).size();
}

但我的metaprogramming-fu不够强大(get_size对于number_value来说是不明确的)。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

您需要在专业化匹配时禁用通用模板:

#include <boost/strong_typedef.hpp>
#include <string>
#include <vector>
#include <iostream>

template <typename T>
typename std::enable_if<!std::is_convertible<T, std::string>::value, std::size_t>::type get_size(T const& v)
{
  return v.size();
}

template <typename T>
typename std::enable_if<std::is_convertible<T, std::string>::value, std::size_t>::type get_size(T const& v)
{
  return static_cast<std::string>(v).size();
}

template <typename T>
bool    is_empty(const T& v)
{
  return (get_size(v) == 0);
}

BOOST_STRONG_TYPEDEF(std::string, number_value)

template <typename T>
void say(T const& v)
{
  if (is_empty(v)) {
    return; // cool, nothing to do!
  }

  std::cout << get_size(v) << "\n";
}

int main()
{
  std::string s;
  number_value n;
  std::vector<std::string> strings;

  say(s);
  say(n);
  say(strings);
}

答案 1 :(得分:0)

简单的方法是为strong-typedefed类型添加函数模板的显式特化,并仅使用底层值的实现:

template <>
void say(number_value const& v)
{
    say(static_cast<std::string>(v));
}