C++ 如何实现这样的模板专门化?
现在,我使用的函数“JoinStrings”只能连接数据类型std::string。我现在需要加入整数。所以我希望重构它。但我失败了。我很高兴听到“你不能这样做”,因为我真的不知道以这种方式重用这些代码是否合理 调用部分:C++ 如何实现这样的模板专门化?,c++,templates,template-specialization,C++,Templates,Template Specialization,现在,我使用的函数“JoinStrings”只能连接数据类型std::string。我现在需要加入整数。所以我希望重构它。但我失败了。我很高兴听到“你不能这样做”,因为我真的不知道以这种方式重用这些代码是否合理 调用部分: int main(int argc, char* argv[]) { vector<int> integers; string str = JoinStrings(integers); cout << str <
int main(int argc, char* argv[]) {
vector<int> integers;
string str = JoinStrings(integers);
cout << str << endl;
}
intmain(intargc,char*argv[]){
向量整数;
string str=连接字符串(整数);
不能追加(分隔符);
}
输出->附加(*iter);
}
}
//应该为IntegerConstForwardIterator声明什么数据类型?
模板
void JoinStrings(常量integerconstforward迭代器&begin,
常量integerconstforward迭代器&end,
常量std::字符串和分隔符,
标准::字符串*输出){
输出->清除();
for(integerconstforward迭代器iter=begin;iter!=end;++iter){
如果(iter!=开始){
输出->附加(分隔符);
}
输出->附加(std::to_字符串(*iter));
}
}
模板
std::string JoinStrings(const ConstForwardIterator&begin,
const constforward迭代器&end,
常量std::字符串和分隔符){
std::字符串输出;
JoinString(开始、结束、分隔符和输出);
返回输出;
}
模板
标准::字符串JoinString(常量容器和容器,
常量std::字符串和分隔符=“”){
返回JoinString(container.begin()、container.end()、分隔符);
}
可以修改代码以实现所需。我将此问题解释为模板专门化练习。(关于推荐的替代方案,请参考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;
....
}
一个更经典的解决方案是使用“标记分派”,但这需要更改更多代码,比如您的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)
模板
void JoinStrings(const std::vector::const_迭代器和begin,
常量std::vector::常量迭代器&end,
常量std::字符串和分隔符,
标准::字符串*输出)
这就是你想要的吗?正如@jogojapan所说,使用std::ostringstream是一个更好的选择
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
template <class ConstForwardIterator>
std::string JoinStrings(const ConstForwardIterator& begin,
const ConstForwardIterator& end,
const std::string& delimiter) {
std::ostringstream oss;
for (ConstForwardIterator iter = begin; iter != end; ++iter) {
if (iter != begin) {
oss << delimiter;
}
oss << *iter;
}
return oss.str();
}
template <class Container>
std::string JoinStrings(const Container &container,
const std::string& delimiter = " ") {
return JoinStrings(container.begin(),
container.end(), delimiter);
}
int main(int argc, char *argv[]) {
std::vector<int> integers;
integers.push_back(1);
integers.push_back(2);
integers.push_back(3);
std::string str = JoinStrings(integers);
std::cout << str << std::endl;
std::vector<std::string> strings;
strings.push_back("MOU");
strings.push_back("BI");
str = JoinStrings(strings);
std::cout << str << std::endl;
return 0;
}
#包括
#包括
#包括
#包括
模板
std::string JoinStrings(const ConstForwardIterator&begin,
const constforward迭代器&end,
常量std::字符串和分隔符){
std::ostringstream oss;
for(ConstForwardIterator iter=begin;iter!=end;++iter){
如果(iter!=开始){
oss怎么会失败?你有没有遇到编译器错误或意外行为?直觉上,我建议你不要使用std::string
来生成输出,而是使用std::ostringstream
。这将解决许多问题——特别是,你甚至不再需要对int
进行专门化的模板。好的,我正在尝试顺便问一句,效率有损失吗?@Mou这取决于你使用它的目的。我想说,可以忽略不计。请先分析一下。@Mou的工作原理,修改易于理解的代码。只有掌握了这一点,才能加快速度,因为许多代码不需要速度,而速度的提高是以错误为代价的。好的,我很高兴听到这个消息。你知道吗r点是这样的重构是不可重新研究的或不实用的。@Mou,我没有试图提出任何观点。只是尝试编写一些看起来像专门化的东西。对不起,这不是我需要的。我需要的是“不合理”或“整型constforward迭代器类型”,而是以另一种方式的功能实现。
template <>
void JoinStrings(const std::vector<int>::const_iterator& begin,
const std::vector<int>::const_iterator& end,
const std::string& delimiter,
std::string* output)
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
template <class ConstForwardIterator>
std::string JoinStrings(const ConstForwardIterator& begin,
const ConstForwardIterator& end,
const std::string& delimiter) {
std::ostringstream oss;
for (ConstForwardIterator iter = begin; iter != end; ++iter) {
if (iter != begin) {
oss << delimiter;
}
oss << *iter;
}
return oss.str();
}
template <class Container>
std::string JoinStrings(const Container &container,
const std::string& delimiter = " ") {
return JoinStrings(container.begin(),
container.end(), delimiter);
}
int main(int argc, char *argv[]) {
std::vector<int> integers;
integers.push_back(1);
integers.push_back(2);
integers.push_back(3);
std::string str = JoinStrings(integers);
std::cout << str << std::endl;
std::vector<std::string> strings;
strings.push_back("MOU");
strings.push_back("BI");
str = JoinStrings(strings);
std::cout << str << std::endl;
return 0;
}