The question is, why only the call to M::operator<<
causes a link error, not the call to std::cout::operator<<
when it should?
The code is as follows:
#include <iostream>
struct M {
inline M() {}
template <typename T>
inline M& operator <<(const T& val) {
std::cout << "ref." << val;
return *this;
}
template <typename T>
inline M& operator <<(T* const& pointer) { // NOLINT
std::cout << "ptr." << pointer;
return *this;
}
};
class PJTest
{
public:
~PJTest()
{
M()
<< "Failed to remove file '" << fname << "' because: stuff\n"; // 25
std::cout
<< "Failed to remove file '" << fname << "' because: stuff\n"; // 28
}
protected:
static auto constexpr fname = "what's in a name?";
};
int main() {
PJTest pt;
}
Compiling with g++ -g -O0 -std=c++11 -Wall -pedantic -Wextra wtf.cc
results in
wtf_test.cc:25: undefined reference to `PJTest::fname'
Note that there is no error for line 28 when it should!
g++ -g -O2 -std=c++11 -Wall -pedantic -Wextra wtf.cc
succeeds.
(g++ 4.8.4 from Ubuntu 14.04LTS) and the behavior is the same with G++ 5.3.0
Compiling with clang++ always fails regardless of optimization level, but again, only for line 25; I know I can fix this by adding constexpr const char* PJTest::fname;
but I want to understand WHY it causes a error in clang++.