【问题标题】:Template specialization for class wrappers类包装器的模板特化
【发布时间】:2021-04-19 07:40:32
【问题描述】:

我不能让我的 int 类包装器在模板专业化中表现得像原始的 int

我准备了这段代码来详细解释我的问题:

#include <iostream>
#include <stdlib.h> 

class Integer
{
  int _v;
public:
  constexpr explicit Integer(int v) : _v(v) {}
  constexpr Integer next() const { return Integer(_v + 1); }
  constexpr operator int() const { return _v;}
};

static constexpr auto integer1 = Integer(1);
static constexpr auto integer2a = Integer(2);
static constexpr auto integer2b = integer1.next();

template <const Integer& i>
void foo_Integer()
{
  static auto foo_id = rand();
  std::cout << foo_id << std::endl;
}

static constexpr auto int1 = 1;
static constexpr auto int2a = 2;
static constexpr auto int2b = int1 + 1;

template <int i>
void foo_int()
{
  static auto foo_id = rand();
  std::cout << foo_id << std::endl;
}

int main()
{
  foo_int<int1>();
  foo_int<int2a>();
  foo_int<int2b>(); // same template specialization as above -> :)

  foo_Integer<integer1>();
  foo_Integer<integer2a>();
  foo_Integer<integer2b>(); // different template specialization -> :(
}

如你所见,运行代码

foo_int<int2a>();
foo_int<int2b>();

使用相同的模板特化,而

foo_Integer<integer2a>();
foo_Integer<integer2b>();

使用不同的模板特化。

从编译器的角度来看,这当然是正确的,因为模板接受 const Integer&amp;,但我希望有其他更好的方法来解决这个问题。

【问题讨论】:

  • fwiw、foo_int&lt;integer2a&gt;;foo_int&lt;integer2b&gt;; 是同一个函数
  • 只是关于术语的注释,这是模板实例化,而不是模板特化。
  • @super - 不,这实际上是正确的术语。该标准也将实例化模板称为特化。

标签: c++ c++17 c++20


【解决方案1】:

您可以轻松地将Integer 设为结构类型 (C++20)。那么它的值就是有效的模板参数。

class Integer
{
public:
  int _v;

  constexpr explicit Integer(int v) : _v(v) {}
  constexpr Integer next() const { return Integer(_v + 1); }
  constexpr operator int() const { return _v;}
};

template <Integer i>
void foo_Integer()
{
  static auto foo_id = rand();
  std::cout << foo_id << std::endl;
}

Live

而且这些值是等价的,即使它们来自不同身份的对象。

【讨论】:

  • 那是黄金。我想知道是否有办法将“_v”设为私有。也许定义一个特定的比较运算符?
  • @c.bear - 不。结构类型本质上是不包含任何秘密的类型。它必须按照定义公开(至少在 C++20 中指定,谁知道未来会带来什么)。
猜你喜欢
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多