【问题标题】:Is it possible to specialize on a typedef and its underlying type separately?是否可以分别专门研究 typedef 及其基础类型?
【发布时间】:2018-08-17 17:44:10
【问题描述】:

简单的例子是 size_t。假设:

typedef uint64_t size_t;

我想以不同的方式专注于 uint64_t 和 size_t:

template <class T>
struct MyType {};

template <>
struct MyType<uint64_t>{
    void operation()() { cout << "uint64_t" << endl; }
};

template <>
struct MyType<size_t>{
    void operation()() { cout << "size_t" << endl; }
}

MyType<1ULL>()();
MyType<static_cast<size_t>(1ULL)>()();

这甚至可能吗?有没有获得相同净效果的技巧?

【问题讨论】:

  • 你可以试试enum class my_size_t : size_t { }
  • 是的,但这种假设假设用户直接使用 my_size_t。试图避免这种情况。
  • 我不认为你可以做你正在尝试的事情。我会用聪明的技巧让别人证明我错了。
  • 这就是我的想法。可能对我一厢情愿。
  • 这是不可能的,因为 typedef 只是一个别名,它不会引入新类型。

标签: c++ templates typedef template-specialization


【解决方案1】:

这是不可能的。

标准(7.1.3,[dcl.typedef])如下:

使用typedef 说明符声明的名称变为typedef-name。在其声明的范围内,typedef-name 在语法上等同于关键字,并以第 8 条中描述的方式命名与标识符关联的类型。 A typedef-name因此, 是另一种类型的同义词typedef-name 不会像类声明 (9.1) 或枚举声明那样引入新类型

【讨论】:

  • 这是我的假设,但编译器以不同方式处理此问题的示例是 printf。 size_t、ptrdiff_t 和其他类型可以直接映射到 uint64_t,但检测、处理和验证方式不同。不过,这可能不是基于类型的定义。
  • @Jaime,请举个具体的例子。在这方面printf() 应该没有什么特别之处。
  • 当然,在 Windows 64 位上,使用 size_t 您可以使用 %tu 或 %Iu(大写 i)作为 printf,但 uint64_t 通常需要 %llu 或 %I64u。这些通过 typedef 映射到相同的类型。与模板无关,但编译器大概可以检测到差异并单独验证。所以希望可以用类型定义来做类似的事情。你的帖子似乎暗示不是:(
  • 如果size_tuint64_t 是同一类型,您可以互换使用这些标志,编译器将无法检测到差异。编译器可以做的是检测sizeof(size_t),然后以不同的方式解释这些标志。
  • @Jaime MSVC 只是警告说“the sizes of types '::size_t' and 'unsigned __int64' might differ on other platforms”。编译时它仍然将这两种类型视为相同。
猜你喜欢
  • 1970-01-01
  • 2014-11-24
  • 2012-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-27
  • 1970-01-01
  • 2017-12-16
相关资源
最近更新 更多