이 예가 도움이됩니까? 나는 std :: forward의 유용한 비 일반적인 예를 찾기 위해 고심했지만, 우리가 인수로 입금하기 위해 현금을 통과하는 은행 계좌의 예에 부딪쳤다.
만약 우리가 계정의 const 버전을 가지고 있다면 우리가 예금 템플릿 <>에 전달할 때 const 함수가 호출 될 것으로 예상해야합니다. 그런 다음 예외가 발생합니다 (이 아이디어는 잠긴 계정이었습니다!)
const 계정이 아닌 계정이 있으면 계정을 수정할 수 있어야합니다.
#include <iostream>
#include <string>
#include <sstream> // std::stringstream
#include <algorithm> // std::move
#include <utility>
#include <iostream>
#include <functional>
template<class T> class BankAccount {
private:
const T no_cash {};
T cash {};
public:
BankAccount<T> () {
std::cout << "default constructor " << to_string() << std::endl;
}
BankAccount<T> (T cash) : cash (cash) {
std::cout << "new cash " << to_string() << std::endl;
}
BankAccount<T> (const BankAccount& o) {
std::cout << "copy cash constructor called for " << o.to_string() << std::endl;
cash = o.cash;
std::cout << "copy cash constructor result is " << to_string() << std::endl;
}
// Transfer of funds?
BankAccount<T> (BankAccount<T>&& o) {
std::cout << "move cash called for " << o.to_string() << std::endl;
cash = o.cash;
o.cash = no_cash;
std::cout << "move cash result is " << to_string() << std::endl;
}
~BankAccount<T> () {
std::cout << "delete account " << to_string() << std::endl;
}
void deposit (const T& deposit) {
cash += deposit;
std::cout << "deposit cash called " << to_string() << std::endl;
}
friend int deposit (int cash, const BankAccount<int> &&account) {
throw std::string("tried to write to a locked (const) account");
}
friend int deposit (int cash, const BankAccount<int> &account) {
throw std::string("tried to write to a locked (const) account");
}
friend int deposit (int cash, BankAccount<int> &account) {
account.deposit(cash);
return account.cash;
}
friend std::ostream& operator<<(std::ostream &os, const BankAccount<T>& o) {
os << "$" << std::to_string(o.cash);
return os;
}
std::string to_string (void) const {
auto address = static_cast<const void*>(this);
std::stringstream ss;
ss << address;
return "BankAccount(" + ss.str() + ", cash $" + std::to_string(cash) + ")";
}
};
template<typename T, typename Account>
int process_deposit(T cash, Account&& b) {
return deposit(cash, std::forward<Account>(b));
}
int main(int, char**)
{
try {
// create account1 and try to deposit into it
auto account1 = BankAccount<int>(0);
process_deposit<int>(100, account1);
std::cout << account1.to_string() << std::endl;
std::cout << "SUCCESS: account1 deposit succeeded!" << std::endl;
} catch (const std::string &e) {
std::cerr << "FAILED: account1 deposit failed!: " << e << std::endl;
}
try {
// create locked account2 and try to deposit into it; this should fail
const auto account2 = BankAccount<int>(0);
process_deposit<int>(100, account2);
std::cout << account2.to_string() << std::endl;
std::cout << "SUCCESS: account2 deposit succeeded!" << std::endl;
} catch (const std::string &e) {
std::cerr << "FAILED: account2 deposit failed!: " << e << std::endl;
}
try {
// create locked account3 and try to deposit into it; this should fail
auto account3 = BankAccount<int>(0);
process_deposit<int>(100, std::move(account3));
std::cout << account3.to_string() << std::endl;
std::cout << "SUCCESS: account3 deposit succeeded!" << std::endl;
} catch (const std::string &e) {
std::cerr << "FAILED: account3 deposit failed!: " << e << std::endl;
}
}
짓다:
cd std_forward
rm -f *.o example
c++ -std=c++2a -Werror -g -ggdb3 -Wall -c -o main.o main.cpp
c++ main.o -o example
./example
예상 출력 :
# create account1 and try to deposit into it
new cash BankAccount(0x7ffee68d96b0, cash $0)
deposit cash called BankAccount(0x7ffee68d96b0, cash $100)
BankAccount(0x7ffee68d96b0, cash $100)
# SUCCESS: account1 deposit succeeded!
delete account BankAccount(0x7ffee68d96b0, cash $100)
# create locked account2 and try to deposit into it; this should fail
new cash BankAccount(0x7ffee68d9670, cash $0)
delete account BankAccount(0x7ffee68d9670, cash $0)
# FAILED: account2 deposit failed!: tried to write to a locked (const) account
# create locked account3 and try to deposit into it; this should fail
new cash BankAccount(0x7ffee68d9630, cash $0)
delete account BankAccount(0x7ffee68d9630, cash $0)
# FAILED: account3 deposit failed!: tried to write to a locked (const) account
Args...&& args
?