【问题标题】:Detect std::size_t type at compilation time to call the right function在编译时检测 std::size_t 类型以调用正确的函数
【发布时间】:2017-09-03 12:33:51
【问题描述】:

管理我自己的存档系统,我有以下虚拟功能:

virtual void OutputArchive::save_unsigned_long_int(unsigned long int i);
virtual void OuptutArchive::save_unsigned_long_long_int(unsigned long long int i);
virtual void InputArchive::load_unsigned_long_int(unsigned long int& i);
virtual void InputArchive::load_unsigned_long_long_int(unsigned long long int& i);

然后,由于某种原因,我还必须管理类型std::size_t,这可能因编译器而异。例如,在 64 位 Linux 上使用 gcc,std::size_tunsigned long int,但在 Windows 64 位上使用 intel,std::size_tunsigned long long int。在第一种方法中,我写了这样的东西:

void OutputArchive::save_size_t(std::size_t i)
{
  if(boost::is_same<std::size_t,unsigned long int>::value)
    this->save_unsigned_long_int((unsigned long int)i);
  else if(boost::is_same<std::size_t,unsigned long long int>::value)
    this->save_unsigned_long_long_int((unsigned long long int)i);
  else { /* error management */ }
}

但是,我对此并不满意:它很丑陋,只能执行一行,类型在编译时是已知的。我想预处理可以做得更好,但我不知道如何开始。欢迎任何帮助。

注意:出于兼容性原因,我不使用 C++11,但我使用 Boost。

【问题讨论】:

  • 看起来更像是 SFINAE 的一个用例。
  • save_unsigned_long_intsave_unsigned_long_long_int?这不是绕过 C++ 重载的整个 reason 吗?为什么这不是 one 函数名称允许在参数中使用多种类型?
  • 然后考虑 paxdiablo 的评论。超载是件好事。而且它完全不排除对它们进行虚拟化。
  • @Caduchon:这是你的错误决定。无论如何,如果你坚持,那就在基类中添加一个非虚拟的重载包装函数,它调用虚拟的。
  • 声明一个save()模板方法。专门为每种数据类型调用适当的虚拟方法。结束。

标签: c++ c-preprocessor preprocessor size-t boost-preprocessor


【解决方案1】:

预处理器对类型一无所知。或范围。或者任何涉及程序语义的东西。预处理器所能处理的只是标记,它们只是对应于一小组词法规则的字符序列。

简而言之,类型在编译时是已知的,但在对应于预处理器的翻译阶段不知道。 C++ 在编译时使用类型信息来确定适当的重载函数,并推断出正确的模板定义。其中任何一个都可能是解决您的问题的合适方法。

可能值得注意的是,C++ 标准只要求size_t 是“无符号整数类型”。它不需要是标准无符号整数类型(参见§3.9.1p1),因此size_t 可能既不是unsigned intunsigned long int 也不是unsigned long long int。 (类似的评论适用于ptrdiff_t 和有符号整数类型。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 2014-07-02
    • 2016-12-05
    • 2021-11-19
    • 1970-01-01
    • 2012-02-13
    相关资源
    最近更新 更多