sfinae 位于类体外部定义的成员函数上

2024-01-10

有点像我的延续上一个问题 https://stackoverflow.com/questions/11694970/c11-style-sfinae-and-function-visibility-on-template-instantiation。我得到的是一堆形成 sfinae 依赖链的函数,如下所示(让“A -> B”表示法意味着 A 的存在取决于 B 的存在):

S::f_base -> S::f -> ns::f_ -> f -> T::f

其中 T 是模板参数。它的实现就像this http://liveworkspace.org/code/9780ef0aa9b85e6464dbf1538ab4ae25:

#include <utility>

struct S;

template <typename T>
auto f(S& s, T const& t) -> decltype(t.f(s), void())
{
    t.f(s);
}

namespace ns
{
    template <typename T>
    auto f_(S& s, T const& t) -> decltype(f(s, t), void())
    {
        f(s, t);
    }
} 

struct S
{
    template <typename T>
    auto f(T const& t) -> decltype(ns::f_(std::declval<S&>(), t), void())
    {
        ns::f_(*this, t);
    }

    template <typename T>
    auto f_base(T const* t_ptr) -> decltype(f(*t_ptr), void())
    {
        f(*t_ptr);
    }
};

struct pass
{
   void f(S&) const
   {
   }
};

struct fail
{

};

int main()
{
    S s;
    s.f(pass()); // compiles
    //s.f(fail()); // doesn't compile
    return 0;
}

并按预期工作。当我尝试移动定义时,问题就出现了S::f and S::f_base在班级之外,例如so http://liveworkspace.org/code/f54caec1993057b576c04d0608b22cdf:

#include <utility>

struct S;

template <typename T>
auto f(S& s, T const& t) -> decltype(t.f(s), void())
{
    t.f(s);
}

namespace ns
{
    template <typename T>
    auto f_(S& s, T const& t) -> decltype(f(s, t), void())
    {
        f(s, t);
    }
} 

struct S
{
    template <typename T>
    auto f(T const& t) -> decltype(ns::f_(std::declval<S&>(), t), void());

    template <typename T>
    auto f_base(T const* t_ptr) -> decltype(f(*t_ptr), void());
};

template <typename T>
auto S::f(T const& t) -> decltype(ns::f_(std::declval<S&>(), t), void())
{
    ns::f_(*this, t);
}

template <typename T>
auto S::f_base(T const* t_ptr) -> decltype(f(*t_ptr), void()) // <---- HERE ---
{
    f(*t_ptr);
}

int main()
{

    return 0;
}

在箭头标记的线上GCC 4.7.1表达了不满:

错误:'decltype ((((S*)0)->S::f((* t_ptr)), void())) S::f_base(const T*)' 的原型与类 ' 中的任何原型都不匹配S'
错误:候选者是: template decltype ((((S*)this)->S::f((* t_ptr)), void())) S::f_base(const T*)

我试图明确指定哪个f我正在使用f_base通过在它前面(在声明和定义中)加上std::declval<S&>().,但错误仍然存​​在。

我知道我可以像这样修改依赖关系图:

S::f_base ->
          -> ns::f_ -> f -> T::f
S::f      ->

to make S::f_base取决于ns::f_随着S::f,但是有没有办法用第一个依赖图来做到这一点?


GCC 4.X 并不是元编程的最佳选择

我设法让它在 4.7.3 中编译(live https://wandbox.org/permlink/6UbfUzOsskrKKgqI) :

#include <utility>

struct S;

template <typename T>
auto f(S& s, T const& t) -> decltype(t.f(s), void())
{
    t.f(s);
}

namespace ns
{
    template <typename T>
    auto f_(S& s, T const& t) -> decltype(f(s, t), void())
    {
        f(s, t);
    }
} 

// some std::void_t like but GCC4.x compatible
template<class T>
struct void_t
{
   using type = typename std::enable_if<std::is_same<T,T>::value >::type;
};

struct S
{
    template <typename T>
    auto f(T const& t) -> decltype(ns::f_(std::declval<S&>(), t), void());

    template <typename T>
    auto f_base(T const* t_ptr) ->  typename void_t< decltype (::f(*std::declval<T const*>()))>::type ;
};


template <typename T>
auto S::f(T const& t) -> decltype(ns::f_(std::declval<S&>(), t), void())
{
    ns::f_(*this, t);
}

// ::f is needed, fail if just 'f'
template <typename T>
auto S::f_base(T const* t_ptr) ->  typename void_t< decltype (::f(*std::declval<T const*>()))>::type
{
    f(*t_ptr);
}
int main()
{

    return 0;
}

Note:

在 GCC4.X 中我看到了一些奇怪的东西,例如:

template<class T>
struct void_t
{
   using type = void;
};

GCC 取代的地方void_t<decltype(expr)>::type by void即使expr无效。这就是为什么我使用这个实现void_t.

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

sfinae 位于类体外部定义的成员函数上 的相关文章

  • Mono 无法保存用户设置

    我在 Mono Ubuntu 上保存用户设置时遇到问题 这是代码示例 private void Form1 Load object sender EventArgs e string savedText Properties Setting
  • 当我单击 C# 中的“取消”按钮时重定向到新页面(Web 部分)

    Cancel button tc new TableCell btnCancel new Button btnCancel Text Cancel btnCancel Click new EventHandler btnCanel Clic
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • 在 Xcode4 中使用 Boost

    有人设置 C Xcode4 项目来使用 Boost 吗 对于一个简单的 C 控制台应用程序 我需要在 Xcode 中设置哪些设置 Thanks 用这个来管理它 和这个
  • 如何在 VS 中键入时显示方法的完整文档?

    标题非常具有描述性 是否有任何扩展可以让我看到我正在输入的方法的完整文档 我想查看文档 因为我可以在对象浏览器中看到它 其中包含参数的描述和所有内容 而不仅仅是一些 摘要 当然可以选择查看所有覆盖 它可能是智能感知的一部分 或者我不知道它并
  • 为什么密码错误会导致“填充无效且无法删除”?

    我需要一些简单的字符串加密 所以我编写了以下代码 有很多 灵感 来自here http www codeproject com KB security DotNetCrypto aspx create and initialize a cr
  • C++11 函数局部静态 const 对象的线程安全初始化

    这个问题已在 C 98 上下文中提出 并在该上下文中得到回答 但没有明确说明有关 C 11 的内容 const some type create const thingy lock my lock some mutex static con
  • 单元测试失败,异常代码为 c0000005

    我正在尝试使用本机单元测试项目在 Visual Studios 2012 中创建单元测试 这是我的测试 TEST METHOD CalculationsRoundTests int result Calculations Round 1 0
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • 如何排列表格中的项目 - MVC3 视图 (Index.cshtml)

    我想使用 ASP NET MVC3 显示特定类型食品样本中存在的不同类型维生素的含量 如何在我的视图 Index cshtml 中显示它 an example 这些是我的代码 table tr th th foreach var m in
  • 在 C 中复制两个相邻字节的最快方法是什么?

    好吧 让我们从最明显的解决方案开始 memcpy Ptr const char a b 2 调用库函数的开销相当大 编译器有时不会优化它 我不会依赖编译器优化 但即使 GCC 很聪明 如果我将程序移植到带有垃圾编译器的更奇特的平台上 我也不
  • 过期时自动重新填充缓存

    我当前缓存方法调用的结果 缓存代码遵循标准模式 如果存在 则使用缓存中的项目 否则计算结果 在返回之前将其缓存以供将来调用 我想保护客户端代码免受缓存未命中的影响 例如 当项目过期时 我正在考虑生成一个线程来等待缓存对象的生命周期 然后运行
  • Silverlight Datagrid:在对列进行排序时突出显示整个列

    我的 Silverlight 应用程序中有一个 DataGrid 我想在对该列进行排序时突出显示整个列 它在概念上与上一个问题类似 Silverlight DataGrid 突出显示整列 https stackoverflow com qu
  • 我应该在应用程序退出之前运行 Dispose 吗?

    我应该在应用程序退出之前运行 Dispose 吗 例如 我创建了许多对象 其中一些对象具有事件订阅 var myObject new MyClass myObject OnEvent OnEventHandle 例如 在我的工作中 我应该使
  • 为什么 Ajax.BeginForm 在 Chrome 中不起作用?

    我正在使用 c NET MVC2 并尝试创建一个 ajax 表单来调用删除数据库记录 RemoveRelation 的方法 删除记录的过程正在按预期进行 删除记录后 表单应调用一个 JavaScript 函数 从视觉效果中删除该记录 Rem
  • 热重载时调用方法

    我正在使用 Visual Studio 2022 和 C 制作游戏 我想知道当您热重新加载应用程序 当它正在运行时 时是否可以触发一些代码 我基本上有 2 个名为 UnloadLevel 和 LoadLevel 的方法 我想在热重载时执行它
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12
  • 如何创建向后兼容 Windows 7 的缩放和尺寸更改每显示器 DPI 感知应用程序?

    我是 WPF 和 DPI 感知 API 的新手 正在编写一个在 Windows 7 8 1 和 10 中运行的应用程序 我使用具有不同每个显示器 DPI 设置的多个显示器 并且有兴趣将我的应用程序制作为跨桌面配置尽可能兼容 我已经知道可以将

随机推荐

  • 我如何要求 Lisp 编译器忽略(标签种类)函数?

    我盯着斯蒂尔的Common Lisp 语言直到我脸色发青 仍然有这个问题 如果我编译 defun x labels y 5 princ x terpri 有时候是这样的 home clisp experiments clisp c q x
  • 信号发射结构

    这个问题在我脑海里萦绕了很多天 但直到现在我才弄清楚 如果我尝试发送一个结构信号 struct radarStruct unsigned char Data unsigned int rate unsigned int timeStamp
  • ADB 设备卡在“连接”状态

    我正在尝试将我的手机连接到 Android Studio 以跟进一些应用程序开发 我目前正在努力将手机正确连接到计算机 因为 ADB 似乎从未连接到设备 当尝试在设备上启动应用程序时 这是 Android Studio 在运行控制台中告诉我
  • 如何向背景图像添加颜色叠加? [复制]

    这个问题在这里已经有答案了 我在 SO 和 Web 上都看到过很多这个问题 但它们都不是我要寻找的 如何仅使用 CSS 将颜色叠加添加到背景图像 HTML 示例 div class testclass div CSS 示例 testclas
  • R 和 ggplot-将 x 轴更改为日期可消除位置闪避

    我一直在使用 ggplot 来创建绘图 并且我总是喜欢水平偏移数据点 这样误差线就不会重叠 我发现当我使用日期数据作为 x 轴时 我失去了偏移数据点的能力 DF data frame Date c 2006 09 01 2007 09 01
  • 我怎样才能停止ajax请求(不要等到响应到来)?

    如果我使用Ajax发送请求并且这个请求需要很长时间 如果我想发送花药请求我该怎么办 当前的行为第二个请求 我做了 等待第一个请求得到响应 NOTE 我想在整个应用程序上执行此行为 任何新请求立即执行 而不是等待旧请求首先完成 我的应用程序使
  • 为什么我必须重新解释指针指针?

    So this static cast代码是完全合法的 int n 13 void pn static cast
  • MS Visual Studio 2012 可以与 Windows Vista 一起使用吗?

    我运行 Windows Vista Business 并想尝试 MS Visual Studio Express 2012 它们兼容吗 兼容性列表在哪里 至少官方没有 http www microsoft com visualstudio
  • 这个 GCD 实现的 getter setter 线程安全并且比 @synchronized 工作得更好吗?对象

    interface ViewController property nonatomic strong NSString someString end implementation ViewController synthesize some
  • wxPython ListCtrl 帮助

    我正在使用 ListCtrl 它会动态填充项目 当项目 激活 双击 Enter 时 它会调用一个函数 def onClick self event 由于没有预设 ID 我如何找出列表中的哪个项目被单击 字符串是作为自身还是事件的一部分传递给
  • Tensorflow、train_step 馈送不正确

    我正在从 Convnetjs 切换到 Tensorflow 并且正在学习读取图像和使用 Tensorflow 训练 CNN 的基础知识 我在两个文件夹中有一堆 160 120 1 的图像 train go 和 train no 所以我使用两
  • 当模板名称是变量时如何使用 Groovy 模板引擎?

    我正在尝试找到一种方法来使用常规变量而不是使用硬编码的模板名称 当前代码如下所示 SCRIPT template groovy html template 我尝试使用嵌套变量扩展 但仍然出现错误 Example def body SCRIP
  • Apple PrefPane 示例无法构建,并出现 clang 错误,同时反对 -fobjc-arc 和 -fobjc-gc

    我正在尝试构建一个首选项窗格作为学习 OS X 开发的一部分 下载苹果的后首选项窗格示例代码 https developer apple com library mac samplecode PrefsPane Introduction I
  • python 上的 Latex:\alpha 和 \beta 不起作用?

    我使用 matplotlib 生成一些图形 并使用乳胶作为图例 更具体地说 我正在尝试使用这样的东西 loglog x x r label alpha legend show 但是 此代码不会在图形上显示图例 并且在关闭图像后出现错误 我正
  • CHtmlview (MFC) 中的 svg

    我无法在 MFC 应用程序中从 CHtmlView 派生的视图中使用 SVG 进行绘制 但是 当我在记事本中复制相同的源并使用 Internet Explorer 打开它时 它正在工作 我的机器上安装的IE版本是IE9 有人可以帮我解决这个
  • 在python中,random.uniform()和random.random()有什么区别?

    在 python 中 random 模块有什么区别random uniform and random random 它们都生成伪随机数 random uniform 从均匀分布生成数字并random random 生成下一个随机数 有什么不
  • 如何在 Google Apps 脚本中缓存对象

    我正在 Google Drive 电子表格的脚本中从 JIRA 获取 JSON 数据 我有一个脚本可以很好地获取数据 而且我几乎只获取该问题的数据 我返回的是 JSON 文本字段 表示有关特定 JIRA 问题的所有数据 我不想每次需要特定
  • TFS 门控签入——如何拒绝部分构建成功签入?

    我有一个构建后脚本 powershell 它会按照预期抛出异常 构建后脚本在 构建后脚本路径 部分的构建定义中定义 该异常记录在构建的 其他错误和警告 部分中 打开门控签入后 即使构建被归类为 部分 因为构建后脚本失败 更改仍然会提交 似乎
  • 将 Google App Engine 数据存储导出到 MySQL?

    我们正在考虑在 Google App Engine 上构建一些基础设施 但我们担心如果它无法扩展 我们将来需要导出数据并在我们自己的服务器上运行 有没有办法从 App Engine 数据存储区导出到 MySQL 就数据导出而言 批量下载器
  • sfinae 位于类体外部定义的成员函数上

    有点像我的延续上一个问题 https stackoverflow com questions 11694970 c11 style sfinae and function visibility on template instantiati