Safe Bool Idiom


How to allow if(myType), but disallow bool b = myType;
C++11’s solution is keyword “explicit” like so:
explicit operator bool() const;
This still allows if(myType) by taking advantage of the fact that there is already an explicit cast to bool with if.
This disallows implicit cast to bool, therefore disallows operation such as comparison and arithmetic operations.

Advertisements

Switch network between Home and Public


Public network is more secure, but private network if more convenient.
To switch between the two on Windows 10:
Right click the wireless icon, then Properties.
It shows two radio buttons to indicate the connection: Public and Private.

I could not find it before because I thought it’s a property of the adapters, and kept looking under “Change adapter settings” in “Network and Sharing Center” in Control Panel. That was a mistake.

Ternary conditional operator is not shortcut of if-else


Reference can be initialized by ?:, but cannot by if-else.
The same is true for const initialization and initialization list on constructors.
Consider this code snippet:

	int a = 0, b = 1, bCondition = false;
	int & c = bCondition ? a : b;
	c = 2;
	_ASSERT(b == 2);
	(bCondition ? a : b) = 3;
	_ASSERT(b == 3);

The root distinction is that ?: is expression but if-else is statement.

Perfect Forwarding: std::forward and std::move


Based on the source code below, here is the forwarding result:
Input parameter                    Forwarded to
int intNonConst:                     (int&)
const int intConst:                  (const int&)
6(just a literal):                        (int&&) or if (int&&) doesn’t exist, to (const int& i)
std::move(intNonConst)):      (int&&)
int IntTemp():                          (int&&)
Why std::forward: otherwise, when a rvalue is passed, e.g. 6, std::move or IntTemp(), it gets forwarded to &, instead of &&.
Why std::move: so that a lvalue such as intNonConst can be treated as rvalue, and therefore be forwarded to &&
Summary: std::forward is to deal with rvalue forwarding, and it does not affect rvalue reference, regardless of constness

int IntTemp() { return 0; }
void TestForwardingFuncCalled(const int& i)
{
	cout << "const &" << endl;
};
void TestForwardingFuncCalled(int& i)
{
	cout << "&" << endl;
};
void TestForwardingFuncCalled(int&& i)
{
	cout << "&& " << endl;
};

template  void TestForwardingTemplateFunc(T&& t)
{
	cout << "Results with std::forward" << endl;
	TestForwardingFuncCalled(std::forward(t));
	cout << "Results without std::forward" << endl;
	TestForwardingFuncCalled(t);
}

void TestForwarding()
{
	int intNonConst = 2;
	const int intConst = 3;
	TestForwardingTemplateFunc(intNonConst); //with std::forward: (int&)", without std::forward: same
	TestForwardingTemplateFunc(intConst); //with std::forward: (const int&)", without std::forward: same
	TestForwardingTemplateFunc(6); //with std::forward: (int&&) or if (int&&) doesn't exist, to (const int& i), without std::forward: (int&)
	TestForwardingTemplateFunc(std::move(intNonConst)); //with std::forward: (int&&), without std::forward: (int&)
	TestForwardingTemplateFunc(IntTemp());  //with std::forward: (int&&), without std::forward: (int&)
}
void main()
{
	TestForwarding();
}