我正在编写一个类似于 QDebug 的简单记录器类,它有一个将数据保存到 QStringList 中的模板方法。代码在这里:
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QTextStream>
class Logger
{
public:
Logger();
~Logger();
template <typename V>
Logger &operator<<(V const &value);
private:
QStringList msg;
};
inline Logger::Logger():
msg(QString("INFO:"))
{}
inline Logger::~Logger()
{
QTextStream out(stderr);
out << msg.join("");
}
template <typename V>
inline Logger &Logger::operator<<(V const &value)
{
msg << log(value);
return *this;
}
inline QString log(QString const &value)
{
return value;
}
inline QString log(int const (&value)[20])
{
return QString("Array");
}
int main(int argc, char *argv[])
{
Logger c;
int a[20] = {};
c << QString("test") << a;
return 0;
}
但是,这不能使用 GCC 4.8.3 进行编译。
$ g++ -I/usr/include/qt4 -L/usr/lib64/qt4 -lQtCore -o test2 test2.cpp
test2.cpp: In instantiation of ‘Logger& Logger::operator<<(const V&) [with V = int [20]]’:
test2.cpp:50:29: required from here
test2.cpp:32:21: error: ‘log’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
msg << log(value);
^
test2.cpp:41:16: note: ‘QString log(const int (&)[20])’ declared here, later in the translation unit
inline QString log(int const (&value)[20])
确实,如果我移动inline QString log(int const (&value)[20])
到开始或提出一个前向声明,它就会编译并运行。但令我困惑的是inline QString log(QString const &value)
工作没有任何问题:
$ ./test2
INFO:testArray
我注意到 QHash 依赖于 qHash 函数,这在本例中是类似的。 QHash 对于用户定义的键类(数组除外,它不能是函数返回类型)工作得非常好。
为什么他们的行为不同?我在这里错过了什么?
感谢您的帮助。
顺便说一句:您能告诉我这个问题的好关键词是什么吗?我尝试过“专业化”“模板”“前向声明”“QHash”和“用户定义类型”的组合,但它们不起作用。
名字log
被查找两次。在模板定义时,执行普通查找。它没有找到任何东西,因为log
此时尚未声明。
然后,在实例化时,仅执行依赖于参数的查找。当参数类型为QString
,搜索全局命名空间QString
在那里声明,所以log(QString)
被发现。但类型int[]
没有任何关联的命名空间,因此参数相关的查找没有任何可搜索的内容,也找不到任何内容。因此出现了错误。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)