模板推导需要自定义隐式转换的场景
Scenarios where template deduction requires user-defined implicit conversion
我有一个 class 模板,其中包含一个重载运算符模板和一个隐式转换构造函数,类似于以下内容:
#include <utility>
template <class A, class B>
class X {
public:
A a;
B b;
X(A a, B b) : a(a), b(b) {}
X(std::pair<A, B> &value) : a(value.first), b(value.second) {}
template <class C>
friend X<A, C> operator+(const X<A, B> &left, const X<B, C> &right) {
return X<A, C>(left.a, right.b);
}
};
int main() {
X<int, int> a(1, 2);
X<int, float> b(1, 2.5f);
std::pair<int, float> c(1, 2.5f);
a + b; // Valid
a + c; // Template deduction error
}
我在另一个问题上找到了 this 答案,但我在这里看不到任何实施该解决方案的方法。 (请注意,第一个参数的第二个模板参数和第二个参数的第一个模板参数相同很重要,实际的运算符实现并不那么简单,但接口是相同的。
@R-Sahu 和您引用的 link 已经回答了您的问题。但是解决方案是为不是 X 的类型提供另一个运算符 +,在扣除 C 之后进行转换,
#include <utility>
template <class A, class B>
class X {
public:
A a;
B b;
X(A a, B b) : a(a), b(b) {}
X(const std::pair<A, B> &value) : a(value.first), b(value.second) {}
template <class C,template <typename, typename> typename O >
friend X<A, C> operator+(const X<A, B> &left, const O<B, C> &right) {
return left + X<B,C>(right);
}
template <class C>
friend X<A, C> operator+(const X<A, B> &left, const X<B, C> &right) {
return X<A, C>(left.a,right.b);
}
};
int main() {
X<int, int> a(1, 2);
X<int, float> b(1, 2.5f);
std::pair<int, float> c(1, 2.5f);
a + b; // Valid
a + c; // Works
}
我有一个 class 模板,其中包含一个重载运算符模板和一个隐式转换构造函数,类似于以下内容:
#include <utility>
template <class A, class B>
class X {
public:
A a;
B b;
X(A a, B b) : a(a), b(b) {}
X(std::pair<A, B> &value) : a(value.first), b(value.second) {}
template <class C>
friend X<A, C> operator+(const X<A, B> &left, const X<B, C> &right) {
return X<A, C>(left.a, right.b);
}
};
int main() {
X<int, int> a(1, 2);
X<int, float> b(1, 2.5f);
std::pair<int, float> c(1, 2.5f);
a + b; // Valid
a + c; // Template deduction error
}
我在另一个问题上找到了 this 答案,但我在这里看不到任何实施该解决方案的方法。 (请注意,第一个参数的第二个模板参数和第二个参数的第一个模板参数相同很重要,实际的运算符实现并不那么简单,但接口是相同的。
@R-Sahu 和您引用的 link 已经回答了您的问题。但是解决方案是为不是 X 的类型提供另一个运算符 +,在扣除 C 之后进行转换,
#include <utility>
template <class A, class B>
class X {
public:
A a;
B b;
X(A a, B b) : a(a), b(b) {}
X(const std::pair<A, B> &value) : a(value.first), b(value.second) {}
template <class C,template <typename, typename> typename O >
friend X<A, C> operator+(const X<A, B> &left, const O<B, C> &right) {
return left + X<B,C>(right);
}
template <class C>
friend X<A, C> operator+(const X<A, B> &left, const X<B, C> &right) {
return X<A, C>(left.a,right.b);
}
};
int main() {
X<int, int> a(1, 2);
X<int, float> b(1, 2.5f);
std::pair<int, float> c(1, 2.5f);
a + b; // Valid
a + c; // Works
}