模板方法什么时候可以使用稍后定义的函数而不需要前向声明?

2024-02-15

我正在编写一个类似于 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(使用前将#替换为@)

模板方法什么时候可以使用稍后定义的函数而不需要前向声明? 的相关文章

  • 用 C# 启动 Windows 服务

    我想启动一个刚刚安装的Windows服务 ServiceBase ServicesToRun if bool Parse System Configuration ConfigurationManager AppSettings RunSe
  • C++ 模板中的名称查找

    我有一些 C 代码 如果没有 fpermissive 选项 就无法再编译 这是我无法分享的专有代码 但我认为我已经能够提取一个简单的测试用例来演示该问题 这是 g 的输出 template eg cpp In instantiation o
  • 如何在 MFC 中调整对话框大小时移动控件?

    我已经在 MFC 中创建了对话框视图 从下图中可以清楚地看到 如滑块控件和编辑框等 当我调整对话框大小时 这些控件不会移动 在此输入图像描述 https i stack imgur com 7OxAK jpg 我想移动控件以适应对话框 但不
  • 泛型与接口的实际优势

    在这种情况下 使用泛型与接口的实际优势是什么 void MyMethod IFoo f void MyMethod
  • 避免集合已修改错误

    Issue 我有以下代码 foreach var ItemA in GenericListInstanceB ItemA MethodThatCouldRemoveAnyItemInGenericListInstanceB 显然我得到一个错
  • 使用静态类型代替变量

    当您的项目不使用命名空间时 有什么方法可以告诉编译器使用静态类型而不是变量吗 例如 我有一个名为 User 的类 它具有各种静态和非静态方法 假设调用了其中一个静态方法GetUser 我想称之为User GetUser 方法来自一个方法 该
  • 异步方法中的异常未被捕获

    下面的代码没有捕获我的OperationCancelEException 它是通过调用抛出的ct ThrowIfCancellationRequested public partial class TitleWindow Window IA
  • async wait 在调用异步方法时返回 Task> 而不是 List

    我正在尝试了解 async wait 的用法 并且研究了一些博客文章 现在我已经编写了一个测试代码 但它没有按照我期望的方式工作 我有一个返回列表的方法 private List
  • 如何在 C++ 中对静态缓冲区执行字符串格式化?

    我正在处理一段对性能要求非常高的代码 我需要执行一些格式化的字符串操作 但我试图避免内存分配 甚至是内部库的内存分配 在过去 我会做类似以下的事情 假设是 C 11 constexpr int BUFFER SIZE 200 char bu
  • C 中“for”循环中的两个变量

    我正在编写一些代码 需要在其中使用两个变量for环形 下面的代码看起来没问题吗 它确实给了我预期的结果 for loop 1 offset loop 2 offset 2 loop 1 gt offset 190 loop 2 lt 190
  • .Net Core 中的脚手架以及解决方案中的多个项目

    我创建了一个针对 net461 的 Net Core MVC6 应用程序 我使用了一个我非常熟悉的项目结构 其中我将数据 模型和服务类放置在单独的类库项目中 并且 Web 项目引用这些项目 当我尝试搭建控制器时 我收到一条错误 指出我正在搭
  • std::string 在 Visual Studio 上的具体行为?

    我有一个项目需要读取 写入大文件 我决定使用 ifstream read 将这些文件一次性放入内存中 放入 std string 中 这似乎是在 C 中执行此操作的最快方法 http insanecoding blogspot com 20
  • 如何使用 libpq 获取双精度值?

    The examples http www postgresql org docs 9 3 interactive libpq example htmllibpq 文档中展示了如何通过将整数值转换为主机字节序表示来获取整数值 我很好奇必须做
  • 需要使用 openssl 加密和解密文件的示例 C 代码

    我正在用 Linux C 编写代码 我需要使用以下命令来加密和解密文件 openssl 目前 我使用系统命令 des3 e nosalt k 0123456789012345 in inp file out out file 进行加密 使用
  • win32 API 和 .NET 框架之间的选择

    我必须开发一个适用于 Windows 的应用程序 该应用程序将能够通过网络摄像头识别手势来控制鼠标 我将使用 vc 2008 进行开发 但我很困惑是使用 NET 框架还是核心 win32 API 性能对于我的应用程序非常重要 根据 Ivor
  • 如何将 Metro 应用部署到桌面?

    我正在尝试将我的 C 应用程序部署到我的 Windows 8 Metro 桌面 我可以在 bin 文件夹中看到部署的文件 但是当我尝试打开它们时 出现以下错误 该应用程序只能在 AppContainer 的上下文中运行 我检查了属性上下文菜
  • 在代码中而不是 XAML 中呈现 UserControl

    我想用RenderTargetBitmap将 UserControl 呈现为位图 而无需为其编写 XAML 当我这样做时 我得到一张空白图像 我是否错过了关键的一步 ValTool Controls VideoFisheyeOverlayC
  • 致命错误 C1001:编译器中发生内部错误(编译器文件“msc1.cpp”,第 1325 行)

    当我编译代码时 错误指向以下类 该错误在两行上突出显示 如下所示 tm validFrom tm validUntil struct t SslCertData final struct t Contact TCHAR Organizati
  • 如何向 ItemsControl 中的 WPF 按钮添加相同的命令

    如何将命令添加到 wpf 按钮 该按钮是ItemsControl并正在修改ItemsSource itself 这是我的 XAML
  • 什么时候使用静态库需要头文件?

    如果我在 Linux 中用 C 创建一个静态库并生成 a 文件 我 或其他人 如何使用该库 例如 我的库定义了一个类 我认为仅仅提供 a 文件是不够的 还需要提供头文件 我如何知道 a 文件必须提供哪些头文件 例如 我是否需要提供我的库代码

随机推荐