std::is_same::value 总是 true 吗?

2024-04-01

我继承了一些如下所示的代码:

///
/// A specializable function for converting a user-defined object to a string value
///
template <typename value_type>
std::string to_string(const value_type &value)
{
    static_assert(!std::is_same<value_type, value_type>::value, "Unspecialized usage of to_string not supported");
    return "";
}

///
/// A specializable function for converting a user-defined object from a string to a value
///
template <typename return_type>
return_type from_string(const std::string &source)
{
    static_assert(!std::is_same<return_type, return_type>::value, "Unspecialized usage of from_string not supported");
}

!std::is_same<value_type, value_type>::value似乎过于冗长。

我应该将这些语句更改为static_assert(false,"...")?

我不确定是否以这种方式表达来处理某种边缘情况,或者是否false确实是等价的。

Is std::is_same<t,t>::value总是正确的?


您发布的代码格式不正确,无需诊断。

替换为static_assert(false, ...)使编译器请注意您的代码格式不正确。代码was以前格式不正确,编译器只是没有注意到它。

我对你的问题有两个解决办法。一种是黑客攻击,但合法。另一个更干净,但需要您编写更多代码。

这个答案的第一部分是为什么你的代码格式不正确。接下来的两个是解决方案。

为什么代码格式错误?

template <typename value_type>
std::string to_string(const value_type &value)
{
  static_assert(!std::is_same<value_type, value_type>::value, "Unspecialized usage of to_string not supported");
  return "";
}

主要模板为to_string不能用任何类型实例化。 C++ 标准要求所有模板(包括主模板)必须具有有效的实例化(用标准术语称为有效的专业化)。 (还有其他要求,例如如果涉及包,则至少一个此类实例化必须具有非空包等)。

你可能会抱怨“它编译并工作了”,但那就是无需诊断方法。 C++ 标准位置zero当编译器遇到“格式错误,无需诊断”的情况时,对编译器执行操作的限制。它可能无法检测到它并愉快地编译“有效”。它可以假设这是不可能的,如果确实发生,则生成格式错误的代码。它可以尝试检测它,失败,然后执行上述任一操作。它可以尝试检测它、成功并生成错误消息。它可以检测到它,成功并生成代码,将您去年在浏览器中查看的每张图像的缩略图通过电子邮件发送给您的所有联系人。

它的格式不正确,不需要诊断。

我自己会避免这样的代码。

现在,有人可能会说有人可以在某个地方专门研究is_same<T,T>回来false,但这也会使您的程序形成错误,作为模板的非法专业化std违反了标准中对模板的要求。

更换!std::is_same<value_type, value_type>::value with false只会让你的编译器意识到你的代码格式不正确,并生成错误消息。从某种意义上说,这是一件好事,因为格式不正确的代码将来可能会以任意方式破坏。

修复它的黑客方法

解决这个问题的愚蠢方法是创建

template<class T, class U>
struct my_is_same:std::is_same<T,U> {};

这承认了专业化漏洞的可能性。这仍然是代码味道。

正确的修复方法

编写这两个内容的正确方法需要做一些工作。

First, to_string and from_string基于标签调度代替模板专业化:

namespace utility {
  template<class T>struct tag_t {};
  template <typename value_type>
  std::string to_string(tag_t<value_type>, const value_type &value) = delete;
  template <typename value_type>
  std::string to_string(const value_type &value) {
    return to_string(tag_t<value_type>{}, value);
  }

  template <typename return_type>
  return_type from_string(tag_t<return_type>, const std::string &source) = delete;
  template <typename return_type>
  return_type from_string(const std::string &source) {
    return from_string(tag_t<return_type>{}, source);
  }
}

目标是最终用户只需执行utility::from_string<Bob>(b) or utility::to_string(bob)它有效。

基础的反弹到标签调度。要自定义,您可以重载标签调度版本。

要实现 to/from 字符串,在命名空间中Bob写出这两个函数:

Bob from_string( utility::tag_t<Bob>, const std::string& source );
std::string to_string( utility::tag_t<Bob>, const Bob& source );

请注意,它们不是模板或模板的专业化。

处理类型std或内置类型,只需在中定义类似的重载namespace utility.

现在,ADL 和标签分派将带您到正确的字符串函数。无需更改名称空间来定义字符串。

如果你打电话to_string or from_string没有有效的tag_t过载,你最终会调用=delete并收到“未找到过载”错误。

测试代码:

struct Bob {
    friend std::string to_string( utility::tag_t<Bob>, Bob const& ) { return "bob"; }
    friend Bob from_string( utility::tag_t<Bob>, std::string const&s ) { if (s=="bob") return {}; exit(-1); }
};

int main() {
    Bob b = utility::from_string<Bob>("bob");
    std::cout << "Bob is " << utility::to_string(b) << "\n";
    b = utility::from_string<Bob>( utility::to_string(b) );
    std::cout << "Bob is " << utility::to_string(b) << std::endl;
    Bob b2 = utility::from_string<Bob>("not bob");
    std::cout << "This line never runs\n";
    (void)b2;
}

实例 http://coliru.stacked-crooked.com/a/acac84a7656b9def.

(Use of friend不是必需的,该函数只需与以下函数位于同一名称空间中即可Bob或之内namespace utility).

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

std::is_same::value 总是 true 吗? 的相关文章

  • 检查两个数是否是彼此的排列?

    给定两个数字 a b 使得 1 例如 123 是 312 的有效排列 我也不想对数字中的数字进行排序 如果您指的是数字的字符 例如 1927 和 9721 则 至少 有几种方法 如果允许排序 一种方法是简单地sprintf将它们放入两个缓冲
  • 如何检查图像对象与资源中的图像对象是否相同?

    所以我试图创建一个简单的程序 只需在单击图片框中更改图片即可 我目前只使用两张图片 所以我的图片框单击事件函数的代码 看起来像这样 private void pictureBox1 Click object sender EventArgs
  • 如何使 Windows 窗体的关闭按钮不关闭窗体但使其不可见?

    该表单有一个 NotifyIcon 对象 当用户单击 关闭 按钮时 我希望表单不关闭而是变得不可见 然后 如果用户想再次查看该表单 可以双击系统托盘中的图标 如果用户想关闭表单 可以右键单击该图标并选择 关闭 有人可以告诉我如何使关闭按钮不
  • 无法使用已与其底层 RCW 分离的 COM 对象。在 oledb 中

    我收到此错误 但我不知道我做错了什么 下面的代码在backrgroundworker中 将异常详细信息复制到剪贴板 System Runtime InteropServices InvalidComObjectException 未处理 通
  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • pthread_cond_timedwait() 和 pthread_cond_broadcast() 解释

    因此 我在堆栈溢出和其他资源上进行了大量搜索 但我无法理解有关上述函数的一些内容 具体来说 1 当pthread cond timedwait 因为定时器值用完而返回时 它如何自动重新获取互斥锁 互斥锁可能被锁定在其他地方 例如 在生产者
  • C++ 子字符串返回错误结果

    我有这个字符串 std string date 20121020 我正在做 std cout lt lt Date lt lt date lt lt n std cout lt lt Year lt lt date substr 0 4 l
  • 在 Visual Studio 2008 上设置预调试事件

    我想在 Visual Studio 中开始调试程序之前运行一个任务 我每次调试程序时都需要运行此任务 因此构建后事件还不够好 我查看了设置的 调试 选项卡 但没有这样的选项 有什么办法可以做到这一点吗 你唯一可以尝试的 IMO 就是尝试Co
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • 如何衡量两个字符串之间的相似度? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 给定两个字符串text1 and text2 public SOMEUSABLERETURNTYPE Compare string t
  • for循环中计数器变量的范围是多少?

    我在 Visual Studio 2008 中收到以下错误 Error 1 A local variable named i cannot be declared in this scope because it would give a
  • 当操作繁忙时,表单不执行任何操作(冻结)

    我有一个使用 C 的 WinForms 应用程序 我尝试从文件中读取一些数据并将其插入数据表中 当此操作很忙时 我的表单冻结并且无法移动它 有谁知道我该如何解决这个问题 这可能是因为您在 UI 线程上执行了操作 将文件和数据库操作移至另一个
  • 将 unsigned char * (uint8_t *) 转换为 const char *

    我有一个带有 uint8 t 参数的函数 uint8 t ihex decode uint8 t in size t len uint8 t out uint8 t i hn ln for i 0 i lt len i 2 hn in i
  • C++ 复制初始化和直接初始化,奇怪的情况

    在继续阅读本文之前 请阅读在 C 中 复制初始化和直接初始化之间有区别吗 https stackoverflow com questions 1051379 is there a difference in c between copy i
  • 如何让Gtk+窗口背景透明?

    我想让 Gtk 窗口的背景透明 以便只有窗口中的小部件可见 我找到了一些教程 http mikehearn wordpress com 2006 03 26 gtk windows with alpha channels https web
  • mysql-connector-c++ - “get_driver_instance”不是“sql::mysql”的成员

    我是 C 的初学者 我认为学习的唯一方法就是接触一些代码 我正在尝试构建一个连接到 mysql 数据库的程序 我在 Linux 上使用 g 没有想法 我运行 make 这是我的错误 hello cpp 38 error get driver
  • 如何使用 std::string 将所有出现的一个字符替换为两个字符?

    有没有一种简单的方法来替换所有出现的 in a std string with 转义 a 中的所有斜杠std string 完成此操作的最简单方法可能是boost字符串算法库 http www boost org doc libs 1 46
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐

  • Gradle - FatJar - 无法找到或加载主类

    我知道这个问题被问了很多并且有很多答案 但我仍然明白 但我不明白为什么 我正在尝试生成一个 jar来自与 gradle 具有依赖关系的项目 我有课src main java Launcher java 其中我有我的main method 有
  • python 中是否可以从子线程中杀死父线程?

    我在 Windows 上使用 Python 3 5 2 我想运行一个 python 脚本 但保证它不会花费超过N秒 如果它does采取超过N秒 应该引发异常 并且程序应该退出 最初我以为我可以在开始时启动一个线程来等待N抛出异常之前的秒数
  • 如何从角度4中的url获取参数?

    我正在尝试从 URL 获取开始日期 网址看起来像http sitename booking startdate 28 08 2017 我的代码如下 aap module ts import NgModule declarations App
  • Maven 无法找到 AEM 原型

    我已经开始解决这个问题很长时间了 我正在处理 Adob e wknd 项目 但我无法通过这个命令 并且大部分工作都是基于它构建的 mvn archetype generate DarchetypeGroupId com adobe gran
  • Google+ 登录在 Android 片段上无法正常工作

    我正在使用 google 登录我的应用程序 当我使用活动完成它的工作魅力之后 我将代码移动到片段中 之后当我尝试登录 google 时 它不起作用 我必须打开片段活动2 次登录 google 谁能告诉我发生了什么代码片段添加在下面 publ
  • Rails 的问题 has_many 关系

    我正在编写一个应用程序 用户既可以创建自己的页面供人们发帖 也可以关注用户创建的页面上的帖子 这是我目前的模型关系的样子 class User lt ActiveRecord Base has many pages has many pos
  • Java 编译时未在源代码中获取该文件

    最近我遇到了一个 Java 问题 我尝试了在网上找到的一些方法 但没有成功 所以我需要帮助 我在 Eclipse 中有一个 Java 项目 我的主要课程是在src programCode UI Main2 java 在那里面 java我尝试
  • 如何优雅地处理Spring Security中未由ControllerAdvice处理的异常?

    我最近在我的 Spring 4 Hibernate Web 应用程序中实现了 Spring Security 来处理登录 注销和不同的用户角色 经过大量阅读后 它现在看起来工作得很好 但我注意到由于错误的 Spring Security 配
  • 锁定用户位置的 Google 地图

    我希望我的应用程序中的谷歌地图始终以用户为中心 并随着他们当前位置的变化而移动 想想 pokemon go 地图实际上是如何随着用户移动的 我当前的最佳实现只是在每次位置更改时用动画更新相机位置 如下所示 update the locati
  • 为什么 parseInt("014") 结果是 12? [复制]

    这个问题在这里已经有答案了 可能的重复 JavaScript parseInt 八进制错误的解决方法 https stackoverflow com questions 850341 workarounds for javascript p
  • 如何使用 Flex 更新 MySql 数据库

    刚刚开始使用 Flex 进行开发 我喜欢它 我已经做了一些简单的应用程序来感受它 没有涉及更新文件或数据库 我需要帮助 如何从 Flex 应用程序 将在 Web 服务器中运行 对 MySql DB 进行查询 我没有看到任何重复的问题 抱歉
  • 当视频在视口中时自动播放 flowplayer 视频

    当视频位于视口中时 是否有任何已知的自动播放视频的方法 我使用以下函数来确定元素何时位于视口中 var isScrolledIntoView function elem get the position of the viewport va
  • BeforeClose VBA 事件在 Cancel = True 时关闭工作簿

    我正在尝试编写一个简短的宏 以防止 Excel 工作簿的用户在不保护第一张工作表的情况下关闭工作簿 该代码显示消息框 但随后继续关闭工作簿 根据我的理解 如果 取消 参数设置为 True 则工作簿不应关闭 Private Sub Workb
  • 如何从填充 datetime.time 值的系列中提取小时、分钟和秒

    Data 0 09 30 38 1 13 40 27 2 18 05 24 3 04 58 08 4 09 00 09 本质上我想做的就是将其分成三列 小时 分钟 秒 我已经尝试过以下代码 但似乎没有一个起作用 train sample t
  • Rails 4 - 通过 link_to 传递参数?

    我有一个表单 根据用户单击哪个链接来显示表单 我希望将不同的隐藏参数传递到记录并在提交时保存 有没有一个好的方法来做到这一点 提前致谢 例如 gt set request project true gt set request admin
  • 按键值对 JSON 数据进行排序

    我目前正在从 discogs API mp3 标签数据 获取 JSON 数据 并希望按键值对结果进行排序 在本例中 我试图获取 Guns n Roses 歌曲的数据 输出的第一首歌曲为 1988 年 而数据实际上有 1987 年的记录 我如
  • 如何在 R 中将树转换为树状图?

    如何将树 Java 程序的输出 转换为 R 中的树状图 目前 我正在使用给出的建议将树转换为 Newick 格式here https stackoverflow com questions 2612579 converting a tree
  • maven webapp将jsps放置在/WEB-INF/jsp中

    我继承了一个使用 NetBeans 内部 ant 构建的 Web 应用程序 所有jsp都驻留在 WEB INF jsp web xml 具有指向 WEB INF jsp somefile jsp 的硬编码链接 如何使用 maven war
  • 非调试模式时在 Visual Studio 输出窗口中显示消息?

    在Java中 你可以使用System out println message 将消息打印到输出窗口 Visual Studio 中的等效项是什么 我知道当我处于调试模式时 我可以使用它来查看输出窗口中的消息 Debug WriteLine
  • std::is_same::value 总是 true 吗?

    我继承了一些如下所示的代码 A specializable function for converting a user defined object to a string value template