在模板类中Bank<T>
,我的目标是为类型Account
到成员函数创建一个重载void Bank<T>::makeTransfer(T, T, const double)
,签名为void Bank<Account>::makeTransfer(Account&, Account&, const double)
。
也就是说,makeTransfer
当使用Account
s 调用时,函数应该接受引用参数,而对于任何其他类型,它应该复制参数。
我的做法是,创建另一个makeTransfer<T>
具有类似签名的函数,但接受的是引用T&
参数而不是。然后,我使用asT
为这个新函数添加了模板特化。Account
T
但是下面的 MWE 无法成功编译,请参阅GDBonline 编译器链接。
#include <cstdio>
#include <functional>
#include <concepts>
class Account {
public:
Account() = default;
Account(const long id, const double balance): _id{id}, _balance{balance} {
printf("Account no.%ld start balance is %f\n", _id, _balance);
}
const long getId() {
return _id;
}
const double getBalance() {
return _balance;
}
void addToBalance(const double sum) {
_balance += sum;
}
private:
long _id;
double _balance;
};
template<typename T> class Bank {
public:
void makeTransfer(T from, T to, const double amount) {
printf("ID %ld -> ID %ld: %f\n", from, to, amount);
}
void makeTransfer(T& from, T& to, const double amount) {}
};
template<> void Bank<Account>::makeTransfer(Account& from, Account& to, const double amount) {
printf("ID %ld -> ID %ld: %f\n", from.getId(), to.getId(), amount);
from.addToBalance(-amount);
to.addToBalance(amount);
printf("Account no.%ld balance is now %f\n", from.getId(), from.getBalance());
printf("Account no.%ld balance is now %f\n", to.getId(), to.getBalance());
}
int main() {
// try with fundamental type as T
Bank<long> bank;
bank.makeTransfer(1000L, 2000L, 49.95);
bank.makeTransfer(2000L, 4000L, 20.00);
// now define a bank with Account instances
Account a{500, 2600};
Account b{1000, 10'000};
Bank<Account> bank2;
bank2.makeTransfer(a, b, 49.95);
bank2.makeTransfer(b, a, 20.00);
//bank2.makeTransfer(std::ref(a), std::ref(b), 49.95);
//bank2.makeTransfer(std::ref(b), std::ref(a), 20.00);
}
编译器抗议无法选择正确的模板实例:
main.cpp:58:21: error: call of overloaded ‘makeTransfer(Account&, Account&, double)’ is ambiguous
58 | bank2.makeTransfer(a, b, 49.95);
| ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~
main.cpp:31:8: note: candidate: ‘void Bank::makeTransfer(T, T, double) [with T = Account]’
31 | void makeTransfer(T from, T to, const double amount) {
| ^~~~~~~~~~~~
main.cpp:38:17: note: candidate: ‘void Bank::makeTransfer(T&, T&, double) [with T = Account]’
38 | template<> void Bank<Account>::makeTransfer(Account& from, Account& to, const double amount) {
| ^~~~~~~~~~~~~
我尝试用 明确注入引用std::ref
,但没有帮助。
使用类似的东西std::same_as<T, Account>
似乎是多余的,因为编译器的所有提示都应该已经在模板特化中可用。
https://godbolt.org/z/9sEaov3K8