假设我有一对相关的模板,我想自动将参数从其中一个模板转换为另一个模板。我怎样才能做到这一点?
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);
}
关于c++ - 相关模板类之间函数参数的自动转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25020680/