C++ 如何实现这样的模板专门化?

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 <

现在,我使用的函数“JoinStrings”只能连接数据类型std::string。我现在需要加入整数。所以我希望重构它。但我失败了。我很高兴听到“你不能这样做”,因为我真的不知道以这种方式重用这些代码是否合理

调用部分:

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;
}