Reputation: 7647
I am not able isolate this error in a small sample to demonstrate here, but the even the error message is so self-contradicting that maybe one can have an idea if this is a bug or not, without testing.
I have a struct that is (presumably, publicly) deriving another one, yet clang insists this is implicitly private inheritance:
error: 'next' is a private member of 'base'
note: constrained by implicitly private inheritance here
struct derived_temp <key> : base <derived>
while g++ compiles fine. I have only changed the actual names of the classes to make messages more readable. The code looks like this:
template </*...*/>
struct base : //...
{
private:
//...
public:
template <typename I> I next(I i) const { return /*...*/; }
//...
};
template <typename /*...*/>
struct derived_temp;
struct key { /*...*/ };
using derived = derived_temp <key>;
template <>
struct derived_temp <key> : base <derived>
{
//...
};
I have tried to keep the form of the code exactly the same as in my project, only changing names and commenting out parts of it.
The error is caused by attempting to call function next()
on a temporary object of type derived
.
My only explanation is that this may be a bug of clang (yet, I cannot reproduce it in a small sample) that forces me to change
struct derived_temp <key> : base <derived>
to the more explicit
struct derived_temp <key> : public base <derived>
Any idea?
Upvotes: 1
Views: 2603
Reputation: 4121
Code:
struct T1 {
int x;
};
struct T2 : T1 {
int y;
};
int main( int argc, char * argv[] ) {
T2 t2;
t2.x = 3;
return t2.x;
}
Building/running:
~ clang blah.cc -o blah; ./blah; echo $?
3
~ clang blah.cc -std=c++11 -o blah; ./blah; echo $?
3
In short: defaults to public inheritance.
I spent a little more time on this to get it closer to the OPs code; this is what I put together (please forgive the typos; I'm using an airgapped machine to test this out):
template <class T>
struct base {
T x;
template <typename I> I blah( I i ) const { return i + x.k.y; }
}
template <class T>
struct derived_temp;
struct key { int y; };
using derived = derived_temp<key>;
template <>
struct derived_temp<key> : base <derived> {
int z;
key k;
};
int main( int argc, char * argv[] ) {
derived d;
d.x = 1;
d.k.y = 2;
d.z = 3;
return 0;
}
Built with:
~ clang --version
clang version 3.4 (tags/RELEASE_34/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
~ clang++ test.cc -o test -std=c++11
I get two basic errors (I'm not quoting the full thing since I'd have to manually type it all):
test.cc:3:5: error: field has incomplete type 'derived_temp<key>'
test.cc:21:5: error: no member named 'x' in 'derived_temp<key>'
As I stared at this, trying to understand both your motivation/intent as well as what the errors said, it occurs to me you're attempting to do circular inheritance to define things in a circular fashion that may not even be possible.
Upvotes: 1
Reputation: 1516
Something is a little off there. Structs should use public inheritance by default. Forget the templates for a moment and the using directive.
Test with the simplest code which sets up your suspected fail case:
struct Base
{
int i;
};
struct Derived : Base
{
};
Now try access i from an instance of Derived. If that works, and it should, start to add features until it has all the same kinds of components as your original code.
Right now I don't have clang to test it myself. So I'm just suggesting a way forward.
Upvotes: 0