为std:::string和char*专门设计的函数模板

5
正如标题所述,我想为字符串和字符指针专门设计一个函数模板。到目前为止,我已经做到了这一点,但我无法弄清楚如何通过引用传递字符串参数。以下是我的代码:链接
#include <iostream>
#include <string.h>
template<typename T> void xxx(T param)
{
std::cout << "General : "<< sizeof(T)  << std::endl;
}

template<> void xxx<char*>(char* param)
{
std::cout << "Char ptr: "<< strlen(param) << std::endl;
}

template<> void xxx<const char* >(const char*  param)
{
std::cout << "Const Char ptr : "<< strlen(param)<<  std::endl;
}

template<> void xxx<const std::string & >(const std::string & param)
{
std::cout << "Const String : "<< param.size()<<  std::endl;
}

template<> void xxx<std::string >(std::string param)
{
std::cout << "String : "<< param.size()<<  std::endl;
}


int main()
{
        xxx("word");
        std::string aword("word");
        xxx(aword);

        std::string const cword("const word");
        xxx(cword);
} 

另外,template<> void xxx<const std::string & >(const std::string & param) 这个东西就是不起作用。

如果我重排原始模板,将参数接受为T&,那么 char * 必须是 char * &,这对于代码中的静态文本来说不是很好。

请帮帮忙!


1
现在它无法编译!你需要把<string.h>加回来,以便使用strlen函数。 - TonyK
3个回答

11

以下代码无法正常工作吗?

template<>
void xxx<std::string>(std::string& param)
{
    std::cout << "String : "<< param.size()<<  std::endl;
}

对于 const std::string 同样适用吗?

话虽如此,如果你有选择的话(通常都是这样),不要特化函数模板,而是重载函数:

void xxx(std::string& param)
{
    std::cout << "String : "<< param.size()<<  std::endl;
}

注意,这不是一个模板。在99%的情况下,这样做是可以的。

(另外,C++没有头文件<string.h>,只是为了向后兼容C而存在。在C++中,C字符串头文件称为<cstring>(注意前面有一个c),但从您的代码来看,实际上您可能是指头文件<string>(没有前缀c)。)


1
啊,对不起关于<string.h>的问题。我会修复它的。 - ali_bahoo
6
需要翻译的内容:A link would be nice as to why it shouldn't be specialized, so here it is: http://www.gotw.ca/publications/mill17.htm这里提供一个链接来解释为什么不应该进行专门化:http://www.gotw.ca/publications/mill17.htm。 - stefaanv
1
@stefaanv:好的,会包含在内。 - Konrad Rudolph
2
@sad_man:不,这在Konrad的回答中提到了,说实话,在此之前我并不知道... - stefaanv
2
你编译过这个代码吗?g++ 4.4.0 不支持它。它会报错:error: template-id 'xxx<std::string>' for 'void xxx(std::string&)' does not match any template declaration - TonyK

0

以下是我发现令人惊讶的精华:

#include <iostream>

template<typename T> void f(T param) { std::cout << "General" << std::endl ; }
template<> void f(int& param) { std::cout << "int&" << std::endl ; }

int main() {
  float x ; f (x) ;
  int y ; f (y) ;
  int& z = y ; f (z) ;
}

这将打印出"General"三次。第一次(float)是预期的,第三次(int&)是一个惊喜。为什么这不起作用?


这是我在使用std::string&时遇到的问题。在模板中传递引用类型似乎有些问题。希望有人能够解释一下。 - ali_bahoo

0

使用基于编译器的类型转换进行编码真的很冒险。

一种方法是使用基于模板的方式,另一种方法是使用不同类型的多态性。

取决于编译器,您可能会得到不同的行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接