C++ 常量QString的显式模板专门化&;导致无法解决的外部问题
然后它就起作用了。实际上也没有性能损失,所以这是一个非常有效的解决方法,但我只想了解这里发生了什么C++ 常量QString的显式模板专门化&;导致无法解决的外部问题,c++,visual-studio-2008,qt,visual-c++,qt4,C++,Visual Studio 2008,Qt,Visual C++,Qt4,然后它就起作用了。实际上也没有性能损失,所以这是一个非常有效的解决方法,但我只想了解这里发生了什么 上面的代码只是一个SSCCE,真正的代码是如果有人感兴趣的话。这个特别的问题与gzopen()/gzdopen()、QuaGzipFilePrivate::open()和QuaGzipFile::open()函数有关。因为您实际上更改了签名,所以我认为您实际上不想专门化函数模板,而是使用重载。下面是使用std::string的完整测试程序(如果问题也可以在标准类中重现,我更倾向于只依赖标准类):
上面的代码只是一个SSCCE,真正的代码是如果有人感兴趣的话。这个特别的问题与
gzopen()/gzdopen()
、QuaGzipFilePrivate::open()
和QuaGzipFile::open()
函数有关。因为您实际上更改了签名,所以我认为您实际上不想专门化函数模板,而是使用重载。下面是使用std::string
的完整测试程序(如果问题也可以在标准类中重现,我更倾向于只依赖标准类):
#包括
模板空隙f(T);
//#定义断裂
#如果定义(断开)
模板void f(std::string const&){
#否则
void f(std::string const&){
#恩迪夫
int main()
{
std::字符串s;
f(s);
}
如果您在此代码中定义了“断开的”,它将不起作用
此行为的原因是编译器基于主模板选择重载。这将永远不会添加常量&
部分。完成此操作后,编译器将查找所选重载的潜在专门化。因为这永远不会推导出专门化所用的符号,所以这一点不会被接受
那么为什么
f(s)
没有获得专业化?对我来说,是的,尝试gcc和叮当声。太棒了。我真是太蠢了,竟然用模板包装。我需要它来实现主要的内部功能,以避免代码重复,但根本没有理由在较低级别上使用模板。现在代码变得非常有意义。至于为什么它不起作用,我想这是MSVS的一个bug,尽管我认为可能我忽略了一些东西。
#include <QFile>
#include <QString>
// this is some sort of low-level C function
void lowLevelOpenFD(int fd)
{
qDebug("Opened by fd: %d", fd);
}
// as well as this one
void lowLevelOpenName(const char *name)
{
qDebug("Opened by name: %s", name);
}
// this is a wrapper around low-level functions
template<typename FileId>
void callLowLevelOpen(FileId id);
template<>
void callLowLevelOpen(const QString &fileName)
{
lowLevelOpenName(QFile::encodeName(fileName).constData());
}
template<>
void callLowLevelOpen(int fd)
{
lowLevelOpenFD(fd);
}
// this is the function where the most stuff happens
template<typename FileId>
void openInternal(FileId id)
{
// lots of useful stuff goes here
// now we call one of the two low level functions
callLowLevelOpen(id);
// more useful stuff
}
// this is high-level interface to the "open by name" function
void openFile()
{
QString name = "file";
openInternal(name);
}
// this is high-level interface to the "open by FD" function
void openFile(int fd)
{
openInternal(fd);
}
int main()
{
openFile();
openFile(17);
return 0;
}
error LNK2019: unresolved external symbol "void __cdecl callLowLevelOpen<class QString>(class QString)" (??$callLowLevelOpen@VQString@@@@YAXVQString@@@Z) referenced in function "void __cdecl openInternal<class QString>(class QString)" (??$openInternal@VQString@@@@YAXVQString@@@Z)
// this is high-level interface to the "open by name" function
void openFile()
{
QString name = "file";
openInternal<const QString&>(name);
}
// this is high-level interface to the "open by name" function
void openFile()
{
QString name = "file";
openInternal<const QString&>(static_cast<const QString&>(name));
}
template<>
void callLowLevelOpen(QString fileName)
{
lowLevelOpenName(QFile::encodeName(fileName).constData());
}
#include <string>
template <typename T> void f(T);
// #define BROKEN
#if defined(BROKEN)
template <> void f(std::string const&) {}
#else
void f(std::string const&) {}
#endif
int main()
{
std::string s;
f(s);
}