命名空间中的模板函数会导致错误

2023-11-27

假设以下代码:

#include <iostream>

template<typename T>
struct Link
{
    Link(T&& val) : val(std::forward<T>(val)) {}

    T val;
};

template<typename T>
std::ostream& operator<<(std::ostream& out, const Link<T>& link)
{
    out << "Link(" << link.val << ")";
    return out;
}

template<typename T>
auto MakeLink(T&& val) -> Link<T>
{
    return {std::forward<T>(val)};
}

namespace Utils {
template<typename Any>
constexpr auto RemoveLinks(const Any& any) -> const Any&
{
    return any;
}

template<typename T>
constexpr auto RemoveLinks(const Link<T>& link) -> decltype(RemoveLinks(link.val))
{
    return RemoveLinks(link.val);
}

} /* Utils */

int main()
{
    int k = 10;

    auto link = MakeLink(MakeLink(k));

    std::cout << link << std::endl;
    std::cout << Utils::RemoveLinks(link) << std::endl;
}

由于某种原因我无法理解,它会生成以下编译错误g++-4.8:

/home/allan/Codes/expr.cpp: In instantiation of ‘constexpr decltype (Utils::RemoveLinks(link.val)) Utils::RemoveLinks(const Link<T>&) [with T = int&; decltype (Utils::RemoveLinks(link.val)) = const int&]’:
/home/allan/Codes/expr.cpp:88:32:   required from ‘constexpr decltype (Utils::RemoveLinks(link.val)) Utils::RemoveLinks(const Link<T>&) [with T = Link<int&>; decltype (Utils::RemoveLinks(link.val)) = const int&]’
/home/allan/Codes/expr.cpp:100:41:   required from here
/home/allan/Codes/expr.cpp:88:32: error: invalid initialization of reference of type ‘const Link<int&>&’ from expression of type ‘const int’
     return RemoveLinks(link.val);
                                ^
/home/allan/Codes/expr.cpp:89:1: error: body of constexpr function ‘constexpr decltype (Utils::RemoveLinks(link.val)) Utils::RemoveLinks(const Link<T>&) [with T = int&; decltype (Utils::RemoveLinks(link.val)) = const Link<int&>&]’ not a return-statement
 }
 ^
/home/allan/Codes/expr.cpp: In function ‘constexpr decltype (Utils::RemoveLinks(link.val)) Utils::RemoveLinks(const Link<T>&) [with T = int&; decltype (Utils::RemoveLinks(link.val)) = const int&]’:
/home/allan/Codes/expr.cpp:89:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

而 clang 3.3 给出:

test.cc:34:12: error: reference to type 'const Link<int &>' could not bind to an lvalue of type 'const int'
return RemoveLinks(link.val);
       ^~~~~~~~~~~~~~~~~~~~~
test.cc:46:25: note: in instantiation of function template specialization 'Utils::RemoveLinks<Link<int &> >' requested here
std::cout << Utils::RemoveLinks(link) << std::endl;

但是,如果命名空间Utils被删除,然后它编译没有错误(gcc 和 clang),并且执行输出:

Link(Link(10))
10

为什么要定义这些模板函数(RemoveLinks)在命名空间中会导致此类错误?


此问题是声明点 (1) 与依赖名称查找 (2) 相结合的问题的结果。

(1)在声明中

template<typename T>
constexpr auto RemoveLinks(const Link<T>& link) -> decltype(RemoveLinks(link.val))

名字RemoveLinks,或者更准确地说,这种超载RemoveLinks,仅可见在完整的声明符之后根据 [basic.scope.pdecl]/1。这尾随返回类型是声明符的一部分,按照 [dcl.decl]/4。另请参阅这个答案.

(2)在表达式中RemoveLinks(link.val), 名字RemoveLinks取决于 [temp.dep]/1,如link.val是依赖的。

如果我们现在查找依赖名称是如何解析的,我们会发现 [temp.dep.res]:

在解析从属名称时,会考虑以下来源的名称:

  • 在模板定义时可见的声明。
  • 来自与来自实例化上下文和定义上下文的函数参数类型相关联的命名空间的声明。

第一个项目符号没有找到第二个过载RemoveLinks由于声明点 (1)。第二个没有找到重载,因为名称空间Util不与任何参数相关联。这就是为什么将所有内容都放在全局命名空间或命名空间中Util按预期工作(实例).

出于同样的原因,使用合格的 ID in the 尾随返回类型 (like -> decltype(Util::RemoveLinks(link.val))在这里没有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

命名空间中的模板函数会导致错误 的相关文章

  • VB.NET 相当于 C# 属性简写吗?

    是否有与 C 等效的 VB NET public string FirstName get set 我知道你能做到 Public Property name As String Get Return name ToString End Ge
  • 为 Visual Studio 2013 编译 Tesseract

    我正在尝试使用tesseract在 Visual Studio 2013 中 我在链接器 gt 输入 不是 libtesseract302 static lib 中使用 libtesseract302 lib 一切都正常 并且已编译并运行
  • 如何为 C 分配的 numpy 数组注册析构函数?

    我想在 C C 中为 numpy 数组分配数字 并将它们作为 numpy 数组传递给 python 我可以做的PyArray SimpleNewFromData http docs scipy org doc numpy reference
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 将 Excel 导入到 Datagridview

    我使用此代码打开 Excel 文件并将其保存在 DataGridView 中 string name Items string constr Provider Microsoft Jet OLEDB 4 0 Data Source Dial
  • 在一个字节中存储 4 个不同的值

    我有一个任务要做 但我不知道从哪里开始 我不期待也绝对不想要代码中的答案 我想要一些关于该怎么做的指导 因为我感到有点失落 将变量打包和解包到一个字节中 您需要在一个字节中存储 4 个不同的值 这些值为 NAME RANGE BITS en
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 使用 Moq 使用内部构造函数模拟类型

    我正在尝试模拟 Microsoft Sync Framework 中的一个类 它只有一个内部构造函数 当我尝试以下操作时 var fullEnumerationContextMock new Mock
  • 如何使用 Mongodb C# 驱动程序连接多个集合

    我需要将 3 个集合与多个集合合并在一起 lookup我在 C 驱动程序中尝试过 它允许我 lookup用户采集但无法执行秒 lookup用于设置集合 有人可以帮忙吗 db Transactions aggregate lookup fro
  • 有人可以提供一个使用 Amazon Web Services 的 itemsearch 的 C# 示例吗

    我正在尝试使用 Amazon Web Services 查询艺术家和标题信息并接收回专辑封面 使用 C 我找不到任何与此接近的示例 所有在线示例都已过时 并且不适用于 AWS 的较新版本 有一个开源项目CodePlex http www c
  • .NET中的LinkedList是循环链表吗?

    我需要一个循环链表 所以我想知道是否LinkedList是循环链表吗 每当您想要移动列表中的 下一个 块时 以循环方式使用它的快速解决方案 current current Next current List First 电流在哪里Linke
  • 用于 C# 的 TripleDES IV?

    所以当我说这样的话 TripleDES tripledes TripleDES Create Rfc2898DeriveBytes pdb new Rfc2898DeriveBytes password plain tripledes Ke
  • Process.Start() 方法在什么情况下返回 false?

    From MSDN https msdn microsoft com en us library e8zac0ca v vs 110 aspx 返回值 true 表示有新的进程资源 开始了 如果由 FileName 成员指定的进程资源 St
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • memset 未填充数组

    u32 iterations 5 u32 ecx u32 malloc sizeof u32 iterations memset ecx 0xBAADF00D sizeof u32 iterations printf 8X n ecx 0
  • Linq-to-entities,在一个查询中获取结果+行数

    我已经看到了有关此事的多个问题 但它们已经有 2 年 或更长 的历史了 所以我想知道这方面是否有任何变化 基本思想是填充网格视图并创建自定义分页 所以 我还需要结果和行数 在 SQL 中 这将类似于 SELECT COUNT id Id N
  • 检查Windows控制台中是否按下了键[重复]

    这个问题在这里已经有答案了 可能的重复 C 控制台键盘事件 https stackoverflow com questions 2067893 c console keyboard events 我希望 Windows 控制台程序在按下某个
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当

随机推荐

  • M_PI 为负值的 CGAffineTransformMakeRotation

    我在用着CGAffineTransformMakeRotation旋转一个UIView在动画块内 我想将其逆时针旋转180 但是当我把 myView animateWithDuration 0 5 myView transform CGAf
  • 关于 Laravel 5.1 安全性

    我是 Laravel 5 1 开发项目的新手 我想了解如何避免安全风险 Laravel 可以保护哪些类型的攻击 什么样的攻击 Laravel 是不安全的 使用中间件是处理授权的好方法 我知道 Laravel 对于 CSRF 攻击是安全的 有
  • pthread:一个 printf 语句在子线程中打印两次

    这是我的第一个 pthread 程序 我不知道为什么 printf 语句在子线程中打印两次 int x 1 void func void p x x 1 printf tid ld x is d n pthread self x retur
  • 如何从列表中删除空列表(Java)

    我已经搜索过这个 但它是用其他语言编写的 例如Python或R 我在列表中有列表 我想删除空列表 例如 abc def ghi jkl mno 我想 abc def ghi jkl mno 如何从列表中删除空列表 谢谢 你也可以尝试这个 l
  • 操作码 (APC/XCache)、Zend、Doctrine 和自动加载器

    我正在尝试使用 APC 或 XCache 作为操作码来缓存我的 php 页面 我将它与 Zend 和 Doctrine 一起使用 但自动加载器出现问题 如果我尝试使用 APC 我会得到以下信息 Fatal error spl autoloa
  • 实体框架和 SQLite,终极操作方法

    我正在尝试让 Entity Framework 6 4 4 2020 年夏季的最新版本 与 SQLite 1 0 113 1 也是 2020 年夏季的最新版本 一起工作 我找到了很多关于如何执行此操作的信息 但这些信息并不总是有帮助 它们常
  • Android 模拟器实例不显示“允许 USB 调试”确认以进行身份​​验证

    我正在尝试在 Android Studio 的 Android 模拟器中运行我的移动应用程序 当我运行该应用程序时 它会提示我选择模拟器实例 当我选择模拟器实例时 应用程序的构建将启动 并且所选的模拟器将启动 构建完成后 Android S
  • 从数据框中插入 RMySQL

    我正在尝试使用 RMySQL 将数据添加到 MySQL 表 我只需要一次添加一行 但它不起作用 我想做的就是这个 dbGetQuery con INSERT INTO names VALUES data 1 1 data 1 2 所以我正在
  • 新创建的 TFS 2010 迭代不可见

    我已经在 TFS 2010 中创建了一个新的迭代 并且不想在新的故事和查询中使用它 但是 迭代不会显示在新的故事窗口中 刷新VS 重新启动VS 切换到其他项目 没有任何帮助 我是团队项目中的项目管理员 并使用我尝试使用它的同一用户创建了迭代
  • 反应原生 Flatlist 导航

    我收到错误 类型错误 无法读取未定义的属性 导航 我不明白如何将导航组件传递给每个子组件 因此当用户按下某个项目时 它可以使用 React Navigation 导航到 employeeEdit 组件 我是新手 如果这是显而易见的 我很抱歉
  • Hibernate Session 在 ConstraintViolationException 后失效

    在抛出约束违反异常后 是否有任何方法可以继续使用线程绑定的休眠会话 我在这里举一个简短的例子 Parent other service load 33 loads a new parent try Parent p new Parent p
  • 将参数传递给 PrimeFaces 星级评定组件?

    我正在尝试利用星级评定来自 PrimeFaces 的组件 但是 它不允许您传入参数 这使得我无法进行查找以从数据库中获取我想要评分的实体 我尝试过类似的事情 但没有成功
  • 在 PHP 中将标题转换为 url 兼容模式的最佳方法?

    http domain name 1 As Low As 10 Downpayment Free Golf Membership 上面的url会报告400 bad request 如何将此类标题转换为用户友好的标题good要求 您可能想使用
  • 显示/隐藏片段并以编程方式更改可见性属性

    这是一个由两部分组成的问题 我所拥有的是一个 3 片段布局 其中当用户点击另一个片段中找到的按钮时 会动态添加第三个片段 FragmentC 然后 添加后 第三个片段有一个最大化 最小化它的按钮 UPDATE 滚动到最后查看SOLUTION
  • 什么是 XML 属性 xmlns:app?

    XML 可以很好地用于 xmlns app http schemas android com apk res auto 但看不到最大字符数 xmlns app http schemas android com tools 这是由 Andro
  • 尝试将 AutoMapper 用于具有子集合的模型,在 Asp.Net MVC 3 中出现 null 错误

    我对 AutoMapper 完全陌生 我有一个如下所示的视图 using Html BeginForm null null FormMethod Post new enctype multipart form data Html Valid
  • 如何在 Windows 上用 Perl 创建图表?

    如何使用 Perl 创建图表 我正在运行创建文本报告的预定作业 我想将其移至下一步 用于管理 并创建一些与之相关的图表 这可能 可行吗 如果我能以某种方式使用 Office 来完成此操作 那就太好了 更新 我将按此顺序调查的解决方案 Spr
  • 如何使用 PHP 在给定的日期范围和时间生成 .ics 文件 [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我试图找到一种有效的方法 根据给定的日期范围 开始日期 结束日期 和提醒时间 使用 PH
  • 离子3|将 InAppBrowser 添加到提供程序时遇到问题

    我需要打开一个指向我的 Ionic 3 项目的链接 当我用 google 搜索时 我看到了 InAppBrowser 插件 实际上这个链接中只有一张图片 所以如果您知道任何其他获取它的方法或直接显示这张图片 这对我来说就足够了 我所做的一切
  • 命名空间中的模板函数会导致错误

    假设以下代码 include