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 位于类体外部定义的成员函数上 的相关文章

  • 通过 CMIS (dotCMIS) 连接到 SP2010:异常未经授权

    我正在使用 dotCMIS 并且想要简单连接到我的 SP2010 服务器 我尝试用 C 来做到这一点 如下所示http chemistry apache org dotnet getting started with dotcmis htm
  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 按成员序列化

    我已经实现了template
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • 在 Windows 窗体中保存带有 Alpha 通道的单色位图会保存不同(错误)的颜色

    在 C NET 2 0 Windows 窗体 Visual Studio Express 2010 中 我保存由相同颜色组成的图像 Bitmap bitmap new Bitmap width height PixelFormat Form
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现

随机推荐

  • 我如何要求 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