Sorry for the title, it is a mouthful, but I could not find a good compromise between readable and specific.
Please take a look to this code snippet. I know it does not make much sense, it is just intended to illustrate the problem I am encountering:
#include <iostream>
using namespace std;
struct tBar
{
template <typename T>
void PrintDataAndAddress(const T& thing)
{
cout << thing.mData;
PrintAddress<T>(thing);
}
private:
// friend struct tFoo; // fixes the compilation error
template <typename T>
void PrintAddress(const T& thing)
{
cout << " - " << &thing << endl;
}
};
struct tFoo
{
friend void tBar::PrintDataAndAddress<tFoo>(const tFoo&);
private:
int mData = 42;
};
struct tWidget
{
int mData = 666;
};
int main()
{
tBar bar;
bar.PrintDataAndAddress(tWidget()); // Fine
bar.PrintDataAndAddress(tFoo()); // Compilation error
return 0;
}
The code above triggers the following error:
source_file.cpp:10:3: error: 'PrintAddress' is a private member of 'tBar' PrintAddress(thing); source_file.cpp:42:6: note: in instantiation of function template >specialization 'tBar::PrintDataAndAddress' requested here bar.PrintDataAndAddress(tFoo()); // Compilation error source_file.cpp:17:7: note: declared private here void PrintAddress(const T& thing)
but only in Clang++. GCC and MSVC are fine with it (you can quickly test that by pasting that code in http://ift.tt/2bynScT)
It seems as if tBar::PrintDataAndAddress<tFoo>(const tFoo&)
is using the same access as tFoo
, where it is befriended. I know this because befriending tFoo
in tBar
fixes this issue. The problem also goes away if tBar::PrintDataAndAddress
is a non-template function.
For the life of me, I have not been able to find anything in the Standard that explains this behavior. I believe it could be a bad interpretation of 14.6.5 - temp.inject, but I can't claim I have read all of it.
Does anyone know if Clang is right failing to compile the above code? Can you please quote the relevant C++ standard text if that is the case?
Aucun commentaire:
Enregistrer un commentaire