1

考虑如下内容:

template <typename T> struct Foo;

template <typename S> struct Bar
{
  template <typename T> operator Foo<T>();

  // ...
};

class Baz
{
  Baz(Foo<int>&);
};

int main()
{
  Bar<float> bar;
  Baz        baz(bar); // Won't work
}

我想使用模板化运算符来指定一系列可能的转换,以避免重复代码/复制和粘贴。但是,当然,现在在注释的代码行上进行的一系列转换将不起作用,因为在 C++ 中,编译器合理地不会考虑所有形式的模板化运算符,因为那将是难以处理的。

如果我改为选择剪切和粘贴,并按如下方式定义 Bar:

template <typename S> struct Bar
{
  operator Foo<int>();
  operator Foo<float>();
  // many more

  // ...
};

现在可以确定并找到链式转换。我想要的是能够吃到我的蛋糕并吃掉它,特别是将运算符定义为模板,而且还提供了一系列指导声明,可以像将转换运算符定义为非模板一样使用:

template <typename S> struct Bar
{
  template <typename T> operator Foo<T>();

  template operator Foo<int>(); // Not valid C++
  template operator Foo<float>(); // Not valid C++
  // ...
};

有没有办法在 C++11/C++14 中实现这一点?是否有人对构建代码有建议,允许不复制转换运算符的定义,但仍然可以使用转换运算符的有限实例化,就好像它们是单独定义的一样?

4

1 回答 1

1

您的问题不在于您的转换运算符声明,而是您的Baz构造函数:

Baz(Foo<int>&);

这需要对Foo<int>. 当您将 a 隐式转换Bar<S>为 aFoo<T>时,您将生成一个临时对象,该对象不能绑定到非常量引用。如果您将其更改为通过引用到常量来获取参数,则它可以工作

Baz(const Foo<int>&);

如果需要,您可以愉快地为特定类型声明特定运算符:

template <typename S> struct Bar
{
    template <typename T> operator Foo<T>();
    operator Foo<bool>();
};

Bar<float> a{};
Foo<int> b = a; //calls operator Foo<T>
Foo<bool> c = a; //calls operator Foo<bool>
于 2015-05-01T15:38:26.583 回答