让我们从一个简单的类 add 方法开始number
:
class number {
int num;
public:
number(int num = 0): num(num) {}
operator int() const { return num; }
};
number add(number t1, number t2) {
return t1 + t2;
}
int main() {
auto result1 = add(1, 2); // auto-casting, works fine
}
现在我们想number
变成一个模板类:
template<class T>
class number {
T num;
public:
number(T num = 0): num(num) {}
operator T() const { return num; }
};
template<class T>
number<T> add(number<T> t1, number<T> t2) {
return t1 + t2;
}
尝试调用add
与我们调用的简单非模板相同的方法,基于(理论上!)基于CTAD:
int main() {
number a = 3; // works, using CTAD
// auto result1 = add(1, 2); // <== what we wish for, but can't find method
// auto result2 = add(a, 2); // this also doesn't work, no ADL here :(
auto result3 = add<int>(1, 2); // this works, but is not what we wish
}
请注意,如果add
是友元函数,则number
根据ADL使用参数之一调用它是可行的:
template<class T>
class number {
T num;
public:
number(T num = 0): num(num) {}
operator T() const { return num; }
friend number add(number t1, number t2) {
return t1 + t2;
}
};
int main() {
number a = 3; // works, using CTAD
auto result1 = add(a, 2); // works, based on ADL
// auto result2 = add(1, 2); // still doesn't work, no ADL here :(
}
任何建议如何允许模板类的行为类似于非模板,在调用 add 时自动转换?
编辑:
这个问题是根据发表的评论编辑的。应该强调的是,对于像add
这样的自动转换这样的通用函数可能是一个错误的想法,但假设该方法非常具体,例如doSomethingWithNumbers
.