Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 常量QString的显式模板专门化&;导致无法解决的外部问题_C++_Visual Studio 2008_Qt_Visual C++_Qt4 - Fatal编程技术网

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