As others have explained, binding the first parameter to _testValue
implies
that T
is volatile bool
, whereas binding the second parameter to true
implies that T
is merely bool
(without the volatile
modifier). The
clang
compiler gives a nice diagnostic:
clang++ -o main -std=c++1y -pedantic -Wall -stdlib=libc++ main.cpp -stdlib=libc++
main.cpp:26:5: error: no matching member function for call to '_setValueSafeFails'
_setValueSafeFails(_testValue, true);
^~~~~~~~~~~~~~~~~~
main.cpp:12:35: note: candidate template ignored: deduced conflicting types for parameter 'T' ('volatile bool' vs. 'bool')
template<typename T> void _setValueSafeFails(T &value, const T setVal) {
^
main.cpp:9:13: warning: incrementing expression of type bool is deprecated [-Wdeprecated-increment-bool]
++value;
^ ~~~~~
main.cpp:25:5: note: in instantiation of function template specialization 'Test::_incrValueSafe<volatile bool>' requested here
_incrValueSafe(_testValue);
^
1 warning and 1 error generated.
make: *** [main] Error 1
Regarding leading underscores: I just avoid them, partly to avoid debates about
what is or isn't strictly legal. I prefer the popular convention: prefix
private variables with m_
, and don't decorate private function names in any
special way. (Leading underscores are de rigeur for private members in Python,
but of course, C++ is a very different language.) For the record, the holy
standard says the following:
17.6.4.3.2 Global names [global.names]
Certain sets of names and function signatures are always reserved to the implementation:
— Each name that contains a double underscore
__
or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use.— Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.