强制执行此模板的更好方法
Better way of enforcing this template?
目前,我有一个这样的函数模板,可以将vector
转换为string
(只是一个自然字符串,用逗号分隔元素):
//the type T must be passable into std::to_string
template<typename T>
std::string vec_to_str(const std::vector<T> &vec);
如您所见,这仅适用于其元素可以传递到内置std::to_string
函数(例如 int
、double
等)的向量。
用注释记录允许的T
是否被认为是一种好的做法?如果没有,我该怎么办?是否有可能以更好的方式强制执行这一点?
使用 static_assert
和一些表达式 SFINAE,你可以得到一个很好的编译时错误消息:
template<typename T>
constexpr auto allowed(int) -> decltype(std::to_string(std::declval<T>()), bool())
{
return true;
}
template<typename>
constexpr bool allowed(...)
{
return false;
}
template<typename T>
std::string vec_to_str(const std::vector<T>& vec)
{
static_assert(allowed<T>(0), "Invalid value type.");
return "";
}
struct foo {};
int main()
{
std::vector<int> v_int;
vec_to_str(v_int);
std::vector<foo> v_double;
vec_to_str(v_double); // static_assert fires here
}
由于std::to_string
是 C++11 功能,我想您可能对 C++11 解决方案持开放态度。在这种特殊情况下,您可以以 sfinae 的方式使用尾随返回类型:
template <typename T>
auto vec_to_str(const std::vector<T>& vec) -> decltype(std::to_string(std::declval<T>()));
如果值类型不适用于to_string
,则将无法替换(并消除该重载)。但是,这不一定是记录和执行规则的最令人赏心悦目的方式。上述 Sfinae 技巧可能也有 C++11 之前的版本,但它不会更漂亮。
一般来说,我会说简单地在评论中记录它是可以的(可能带有 doxygen 标签,如 tparam
)。如果你愿意,你可以使用概念检查机制,以Boost.Concept-Check的风格。
作为旁注,对于这种特定情况,我可能会建议您依赖std::ostream
operator <<
而不是to_string
函数,因为自定义类型(例如,2D 向量或其他东西)更有可能配备重载以输出到流。
在概念到来之前,您可以将decltype
与匿名类型参数一起使用:
template<typename T,
typename = decltype(std::to_string(std::declval<T>()))>
std::string vec_to_str(const std::vector<T> &vec);
相关文章:
- 初始化具有非默认构造函数的std::数组项的更好方法
- Protobuf中重复字段的问题.使用重复字段进行序列化/反序列化的更好方法是什么?
- 编写按初始值循环的循环的更好方法是什么
- 用 c++ 为游戏制作"bullet"的更好方法?
- 在CMakeLists中包含目录的更好方法.txt
- 将QDomDocument数据用作文本的更好方法
- C++ - 创建具有相同字符的特定大小的以 null 结尾的 c 样式字符串的更好方法
- 在 sqlite3 中批量插入的更好方法C++
- 设计许多单例代码结构的更好方法
- 使用继承的类模板避免公共成员不可见和源代码膨胀/重复的更好方法
- 在初始化列表中初始化数组的更好方法
- 将对象从一个 std::d eque 移动到另一个的更好方法
- 请告诉我在巴泽尔拥有多平台工作空间的更好方法
- 构造具有大量数据的对象的更好方法(C++)
- 从2D矢量中找出最小尺寸的向量元素的更好方法
- 在C++中创建不可变对象的更好方法
- 在构造函数中组织初始值设定项列表的更好方法
- std::copy with return values - 防止"expression: string iterators incompatible"的更好方法?
- 删除数组成员的更好方法是什么?
- 在C 中操作数据的更好方法是什么