在我使用C ++ 98编写代码时,我收到一个奇怪的编译器警告,我不明白:(见:
我有一个文件TemplateSpecialization.hpp:
namespace TemplateNamespace
{
template <typename T> T getParam(int param)
{
return static_cast<T>(param);
}
}
struct A
{
A () : aaa(10) {}
int aaa;
template <typename T> T getAaa()
{
return TemplateNamespace::getParam<T>(aaa);
}
};
和一个文件TemplateSpecialization.cpp:
#include "TemplateSpecialization.hpp"
#include <string>
#include <sstream>
namespace TemplateNamespace {
template<> std::string getParam<std::string>(int param)
{
std::stringstream ss;
ss << param;
return ss.str();
}
}
当我在其他.CPP文件中的任何地方调用此函数时,例如
的Test.cppA a; std::string s = a.getAaa<std::string>();
使用gcc版本4.8.2编译所有内容我收到此警告:
In file included from /var/fpwork/sokeks/Test.cpp:22:0:
/var/fpwork/sokeks/TemplateSpecialization.hpp: In instantiation of 'T TemplateNamespace::getParam(int) [with T = std::basic_string<char>]':
/var/fpwork/sokeks/TemplateSpecialization.hpp:15:50: required from 'T A::getAaa() [with T = std::basic_string<char>]'
/var/fpwork/sokeks/Test.cpp:161:43: required from here
/var/fpwork/sokeks/TemplateSpecialization.hpp:5:36: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
return static_cast<T>(param);
^
我完全不明白,是什么导致了这个警告!为什么所有编译器都指向专门的模板函数!?究竟是什么意思?我使用std :: string,而不是const char *。
提前求助!
答案 0 :(得分:3)
这是一个可见性问题:专门化是另一个编译单元,当需要实例化模板时,它不可见。将模板和声明放入头文件中,将完全专用的函数的定义放入cpp文件中并使用一些包含保护:
TemplateSpecialization.hpp
#pragma once
#include <string>
#include <sstream>
namespace TemplateNamespace
{
template <typename T> T getParam(int param)
{
return static_cast<T>(param);
}
template<> std::string getParam<std::string>(int param);
}
struct A
{
A() : aaa(10) {}
int aaa;
template <typename T> T getAaa()
{
return TemplateNamespace::getParam<T>(aaa);
}
};
TemplateSpecialization.cpp
#include "TemplateSpecialization.hpp"
template<> std::string TemplateNamespace::getParam<std::string>(int param)
{
std::stringstream ss;
ss << param;
return ss.str();
}