- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
现在,我使用的函数“JoinStrings”只能连接数据类型 std::string。我现在需要加入整数。所以希望重构一下。但是我失败了。我很高兴听到“你不能这样做”,因为我真的不知道以这种方式重用这些代码是否合理。
调用部分:
int main(int argc, char* argv[]) {
vector<int> integers;
string str = JoinStrings(integers);
cout << str << endl;
}
我没能实现的部分:
#include <string>
template <class ConstForwardIterator>
void JoinStrings(const ConstForwardIterator& begin,
const ConstForwardIterator& end,
const std::string& delimiter,
std::string* output) {
output->clear();
for (ConstForwardIterator iter = begin; iter != end; ++iter) {
if (iter != begin) {
output->append(delimiter);
}
output->append(*iter);
}
}
// What data type should be declared for IntegerConstForwardIterator?
template<>
void JoinStrings(const IntegerConstForwardIterator& begin,
const IntegerConstForwardIterator& end,
const std::string& delimiter,
std::string* output) {
output->clear();
for (IntegerConstForwardIterator iter = begin; iter != end; ++iter) {
if (iter != begin) {
output->append(delimiter);
}
output->append(std::to_string(*iter));
}
}
template <class ConstForwardIterator>
std::string JoinStrings(const ConstForwardIterator& begin,
const ConstForwardIterator& end,
const std::string& delimiter) {
std::string output;
JoinStrings(begin, end, delimiter, &output);
return output;
}
template <class Container>
std::string JoinStrings(const Container& container,
const std::string& delimiter = " ") {
return JoinStrings(container.begin(), container.end(), delimiter);
}
最佳答案
可以修改代码来实现你想要的。我将此问题解释为模板特化练习。 (对于推荐的替代方案,请关注 jogojapan 的评论)
前言:我期待它能工作,但(尽管它编译)它没有因为通用版本仍然是更好的匹配:
template<template <class> class Cont >
void JoinStrings(const typename Cont<int>::const_iterator& begin,
const typename Cont<int>::const_iterator& end,
const std::string& delimiter,
std::string* output) {
std::clog << "specialized called" << std::endl;
....
}
所以,我不得不求助于旧的enable_if
(为了简洁起见,我在这里使用c++11,经过一些努力可以变成C++98)。使用您的 main
代码,将调用专用版本。
解决方案
#include<type_traits>
....
template <class ConstForwardIterator,
class = typename std::enable_if<not std::is_same<typename std::decay<decltype(*std::declval<ConstForwardIterator>())>::type, int>::value>::type
>
void JoinStrings(const ConstForwardIterator& begin,
const ConstForwardIterator& end,
const std::string& delimiter,
std::string* output) {
std::clog << "generic called" << std::endl;
std::clog << std::trace() << std::endl;
}
template <class ConstForwardIterator,
class = typename std::enable_if<std::is_same<typename std::decay<decltype(*std::declval<ConstForwardIterator>())>::type, int>::value>::type,
class Tag = void
>
void JoinStrings(const ConstForwardIterator& begin,
const ConstForwardIterator& end,
const std::string& delimiter,
std::string* output) {
std::clog << "special called" << std::endl;
....
}
比较经典的方案是使用“标签派发”http://www.boost.org/community/generic_programming.html#tag_dispatching ,但这需要更改更多代码,例如您的 JoinString 容器版本。
受限解决方案:如果您希望代码仅适用于 std::vector
,则解决方案要简单得多:
template <>
void JoinStrings(const std::vector<int>::const_iterator& begin,
const std::vector<int>::const_iterator& end,
const std::string& delimiter,
std::string* output)
关于c++ - 如何实现这样的模板特化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17267313/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!