C++ SFINAE:const char[] 与 std::string 的 is_constructible

2024-04-18

我正在尝试禁用具有非 std::string 可构造类型的 ctor。我的第一次尝试是这样的:

#include <iostream>

struct A
{
    template <typename U, typename = typename std::enable_if<std::is_constructible<std::string, U>::value>::type>
    A(U&& val)
    {
        std::cout << "A(std::string&& val)" << std::string(std::forward<U>(val)) << std::endl;
    }

    template <typename U, typename = typename std::enable_if<not std::is_constructible<std::string, U>::value>::type>
    A(U&& val)
    {
        std::cout << "A(int&& val)" << val << std::endl;
    }
};

int main()
{
    A a1(1);
    A a2("hello");
    A a3(std::string("hello"));
}

但是编译失败了

A a1(1);

并出现以下错误消息:

错误 C2535: 'A::A(U &&)': 成员函数已定义或声明 (活生生的例子 https://wandbox.org/permlink/IVKLqPY1aSj5Zt5q).

这意味着 SFINAE 的两个条件都成功,并且两个因子都被使用。

我继续尝试以下方法:

#include <iostream>

struct A
{
    template <typename U>
    A(U&& val, typename std::enable_if<std::is_constructible<std::string, U>::value>::type* = nullptr)
    {
        std::cout << "A(std::string&& val)" << std::string(std::forward<U>(val)) << std::endl;
    }

    template <typename U>
    A(U&& val, typename std::enable_if<not std::is_constructible<std::string, U>::value>::type* = nullptr)
    {
        std::cout << "A(int&& val)" << val << std::endl;
    }
};

int main()
{
    A a1(1);
    A a2("hello");
    A a3(std::string("hello"));
}

幸运的是它编译并运行良好(活生生的例子 https://wandbox.org/permlink/yq67DhcV6l2GQi6O).

到目前为止,我对第二个解决方案非常满意,但我不太明白为什么使用模板化参数启用/禁用 ctor 的第一种方法不起作用。


条件不同时成立,那是不可能的。您可以确信第二种方法有效,如果两者都成立,则不会发生这种情况。

重要的是要记住,默认模板参数不是函数模板签名的一部分。如果我们将两个 c'tors 简化为他们的签名,我们会得到:

template <typename U, typename>
A(U&& val)
{
}

template <typename U, typename>
A(U&& val)
{
}

并且两者是相同的。所以发生的事情是模板参数推导U并尝试进行替换以查看选择哪个重载。尽管我们无法完成其中一个重载的模板参数推导(其中一个重载中总是没有考虑最后一个参数),但在尝试推导过程时,我们仍然发现两个具有相同签名的模板。因此该程序变得格式错误。

第二种方法有效,因为签名本身取决于enable_if正在评估中。这就是为什么两个重载之一总是会被默默地删除,就好像它从未存在过一样。

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

C++ SFINAE:const char[] 与 std::string 的 is_constructible 的相关文章

  • Tensorflow 中的自定义资源

    由于某些原因 我需要为 Tensorflow 实现自定义资源 我试图从查找表实现中获得灵感 如果我理解得好的话 我需要实现3个TF操作 创建我的资源 资源的初始化 例如 在查找表的情况下填充哈希表 执行查找 查找 查询步骤 为了促进实施 我
  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • 赋值运算符和复制构造函数有什么区别?

    我不明白C 中赋值构造函数和复制构造函数之间的区别 是这样的 class A public A cout lt lt A A lt lt endl The copy constructor A a b The assignment cons
  • 捕获 foreach 条件中抛出的异常

    我有一个foreach在 foreach 本身的条件下循环期间中断的循环 有没有办法try catch抛出异常然后继续循环的项 这将运行几次 直到异常发生然后结束 try foreach b in bees exception is in
  • 在 C++11 中省略返回类型

    我最近发现自己在 C 11 模式下的 gcc 4 5 中使用了以下宏 define RETURN x gt decltype x return x 并编写这样的函数 template
  • 有什么工具可以说明每种方法运行需要多长时间?

    我的程序的某些部分速度很慢 我想知道是否有我可以使用的工具 例如它可以告诉我可以运行 methodA 花了 100ms 等等 或者类似的有用信息 如果您使用的是 Visual Studio Team System 性能工具 中有一个内置分析
  • Guid 应包含 32 位数字和 4 个破折号

    我有一个包含 createuserwizard 控件的网站 创建帐户后 验证电子邮件及其验证 URL 将发送到用户的电子邮件地址 但是 当我进行测试运行时 单击电子邮件中的 URL 时 会出现以下错误 Guid should contain
  • 获取从属性构造函数内部应用到哪个属性的成员?

    我有一个自定义属性 在自定义属性的构造函数内 我想将属性的属性值设置为属性所应用到的属性的类型 是否有某种方式可以访问该属性所应用到的成员从我的属性类内部 可以从 NET 4 5 using CallerMemberName Somethi
  • 是否有与 C++11 emplace/emplace_back 函数类似的 C# 函数?

    从 C 11 开始 可以写类似的东西 include
  • 为什么 FTPWebRequest 或 WebRequest 通常不接受 /../ 路径?

    我正在尝试从 ftp Web 服务器自动执行一些上传 下载任务 当我通过客户端甚至通过 Firefox 连接到服务器时 为了访问我的目录 我必须指定如下路径 ftp ftpserver com AB00000 incoming files
  • 范围和临时初始化列表

    我试图将我认为是纯右值的内容传递到范围适配器闭包对象中 除非我将名称绑定到初始值设定项列表并使其成为左值 否则它不会编译 这里发生了什么 include
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 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 方法存在 这里的问题是 我试图以
  • UWP 无法在两个应用程序之间创建本地主机连接

    我正在尝试在两个 UWP 应用程序之间设置 TCP 连接 当服务器和客户端在同一个应用程序中运行时 它可以正常工作 但是 当我将服务器部分移动到一个应用程序并将客户端部分移动到另一个应用程序时 ConnectAsync 会引发异常 服务器未
  • Qt - 设置不可编辑的QComboBox的显示文本

    我想将 QComboBox 的文本设置为某些自定义文本 不在 QComboBox 的列表中 而不将此文本添加为 QComboBox 的项目 此行为可以在可编辑的 QComboBox 上实现QComboBox setEditText cons
  • 通过等待任务或访问其 Exception 属性都没有观察到任务的异常

    这些是我的任务 我应该如何修改它们以防止出现此错误 我检查了其他类似的线程 但我正在使用等待并继续 那么这个错误是怎么发生的呢 通过等待任务或访问其 Exception 属性都没有观察到任务的异常 结果 未观察到的异常被终结器线程重新抛出
  • 运行代码首先迁移更新数据库时出错

    我在迁移到数据库时遇到问题 并且似乎找不到我遇到的错误的答案 System MissingMethodException Method not found System Data Entity Migrations Builders Tab
  • 为什么 Ajax.BeginForm 在 Chrome 中不起作用?

    我正在使用 c NET MVC2 并尝试创建一个 ajax 表单来调用删除数据库记录 RemoveRelation 的方法 删除记录的过程正在按预期进行 删除记录后 表单应调用一个 JavaScript 函数 从视觉效果中删除该记录 Rem
  • boost::program_options:带有固定和可变标记的参数?

    是否可以在 boost program options 中使用此类参数 program p1 123 p2 234 p3 345 p12 678 即 是否可以使用第一个标记指定参数名称 例如 p 后跟一个数字 是动态的吗 我想避免这种情况
  • 如何确定母版页中正在显示哪个子页?

    我正在母版页上编写代码 我需要知道正在显示哪个子 内容 页面 我怎样才能以编程方式做到这一点 我用这个 string pageName this ContentPlaceHolder1 Page GetType FullName 它以 AS

随机推荐