我希望这个模板化代码能够用于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来说是不明确的)。
有什么建议吗?
答案 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));
}