c++ - 相关模板类之间函数参数的自动转换

标签 c++ templates c++11 type-conversion

假设我有一对相关的模板,我想自动将参数从其中一个模板转换为另一个模板。我怎样才能做到这一点?

template<int a> struct bar;

template<int a, int b> struct foo {
  operator bar<a> const (); // operator-based conversion
};

template<int a> struct bar : public foo<a, a> {
  bar() { }
  template<int b> bar(const foo<a, b>&) { } // constructor-based conversion
};

template<int a, int b> foo<a, b>::operator bar<a> const () { return bar<a>(); }

template<int a> void f(bar<a> x, bar<a> y) { }

int main() {
  bar<1> x;
  foo<1, 2> y;
  f(x, y);
}

对此,gcc 4.8.3 说:

template argument deduction/substitution failed: ‘foo<1, 2>’ is not derived from ‘bar<a>’

意图是 f 的第二个参数从 foo<1,2> 转换而来至 bar<1>通过我控制的一些代码。但显然,模板化转换构造函数和非模板化转换运算符都不适用于这种情况。我可以使用任何成语来完成这项工作吗?

最佳答案

模板参数推导需要精确匹配(正如 Xeo 在 comments 中指出的那样,如果需要,将应用单个标准转换序列(第 4 条)),并且不考虑用户定义的转换。所以它无法推导出模板参数 a从第二个参数到 f() (类型为 foo<1,2> )。解决此问题的一种方法是将第二个参数类型转换为非推导上下文。那么a将仅从第一个参数推导出来,您的代码将编译。

#include <functional>
#include <memory>

template<typename T>
struct identity
{
  using type = T;
};

template<int a> struct bar;

template<int a, int b> struct foo {
  operator bar<a> const (); // operator-based conversion
};

template<int a> struct bar : public foo<a, a> {
  bar() { }
  template<int b> bar(const foo<a, b>&) { } // constructor-based conversion
};

template<int a, int b> foo<a, b>::operator bar<a> const () { return bar<a>(); }

template<int a> void f(bar<a> x, typename identity<bar<a>>::type y) { }
//                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
int main() {
  bar<1> x;
  foo<1, 2> y;
  f(x, y);
}

Live demo

关于c++ - 相关模板类之间函数参数的自动转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25020680/

相关文章:

c++ - Boost异步主线程回调

c++ - 有效处理选项

c++ - 将模板类作为模板的模板类将无法编译

c++ - 为什么这个函数模板调用有效?

c++ - 将文本文件的内容逐个字符地读取到 vector 中,而不跳过空格或换行符

c++ - 模板参数列表短路?

c++ - 可变参数模板值作为结构的模板参数

c++ - g++4.7.3 和 g++4.8 的 undefined reference ?

c++ - 将 std::tr1::shared_ptr 与 std::function/std::bind 混合会导致较新的 gcc 出现编译器错误

c++ - 在不提供定义的情况下覆盖函数有什么意义?