【问题标题】:C++ : Copy-constructing from different instantiationC ++:从不同的实例化复制构造
【发布时间】:2021-05-12 23:17:03
【问题描述】:

我希望能够使用不同的“颜色”实例来复制构造Particle<Color::X>。不同的实例化可能包含一组非常不同的成员,但它们都有任意数量的共同成员(下面由 intensity 举例说明)必须由 ctor 复制。

当然,有问题的 ctor 必须不接受不是 Particle 实例化类型的对象。

Color 中可能有无限数量的成员,因此手动编写接受每个变体的构造函数是不切实际的。

我应该使用 SFINAE,还是有更简单的方法来实现这一点?

enum class Color
{
    RED,
    GREEN,
    BLUE
};

template <enum Color>
struct Particle
{
    int intensity;

    Particle(int i) : intensity{i} {};
};

auto main() -> int
{
    Particle<Color::RED> p1{42};
    // Particle<Color::BLUE> p2(p1); <- How do I make this compile?
}

【问题讨论】:

  • 为什么你认为你需要 SFINAE?
  • @largest_prime_is_463035818 很难弄清楚如何使用直接模板来做到这一点。我有一种模糊的直觉类型特征,或者 SFINAE 在这里可能会帮助我,但我显然不是专家。
  • Nitpic:如果某物接受相同的类型,则它只是一个复制构造函数。单参数构造函数可以称为转换构造函数。

标签: c++ templates enums copy-constructor


【解决方案1】:

如果您想要一个接受其他实例化实例的复制构造函数,那么您只需要一个接受任何实例化实例的复制构造函数:

enum class Color
{
    RED,
    GREEN,
    BLUE
};

template <Color c>
struct Particle
{
    int intensity;

    Particle(int i) : intensity{i} {};

    template <Color other_c>
    Particle(const Particle<other_c>& other) : intensity{other.intensity} {};
};

int main() {
    Particle<Color::RED> p1{42};
    Particle<Color::BLUE> p2(p1); 
}

正如 Caleth 在评论中指出的那样,严格来说,当它将一种类型转换为另一种类型时,它是一个转换构造函数。 T 类型的复制构造函数接受 Ts。


请注意,在您的代码中,模板参数未命名。我想这是混乱的一部分。在您的代码中,如果不使用特征,您实际上无法知道 Color 的给定实例化 Particle 是什么。即使在模板定义中,您也无法访问粒子颜色,因为它没有名称。我在上面改变了这个。虽然如果你不想浪费一个成员只是为了存储 ColorParticle 但想从给定的实例中推断出它,你可以这样做:

template <typename T> constexpr Color particle_color;
template <Color c> constexpr Color particle_color<Particle<c>> = c;

用法例如:

static_assert( particle_color<decltype(p2)> == Color::BLUE);

Live Demo

【讨论】:

  • @Talmid 也许您对没有名称的模板参数感到困惑。在不更改模板的情况下,您实际上确实需要一个特征来了解 Color 的给定实例化 Particle 是什么。即使在模板定义中,您目前也无法访问它,因为它没有名称
  • @TedLyngmo 不需要 sfinae,所以也不需要静态断言。 (除非 OP 实际上想要更多尚未提及的内容)
  • @TedLyngmo 如果我理解正确的话,有办法改变它meta.stackexchange.com/a/364263/358287。我会尽快尝试,现在你提到它我意识到它实际上是多么痛苦
  • @Talmid 让我看看能否以某种方式将其纳入答案
  • @TedLyngmo 不知何故,我被我的第一印象愚弄了,我想相信某些事情会永远改变。现在我设法改变它感觉就像一个很大的解脱。我必须安装一个浏览器插件才能轻松阅读,这有点奇怪,但如果是这样,那就是那样。有些东西我们可以改变(字体)有些我们不能;)
猜你喜欢
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-05
  • 2015-12-04
  • 1970-01-01
  • 2013-06-14
相关资源
最近更新 更多