I obtain different results from dynamic_cast when using different compilers - c++

The assertion in the following program gives different results according to the compiler used: in GCC 4.4 the assertions fails, while in CLang does not. It looks like GCC does not like V being private in C. Is this a bug?
#include <cassert>
class V {
public:
virtual ~V() { };
};
template<class T>
class C : public T, private V {
public:
static V* new_() {
return new C();
}
};
struct MyT {
};
typedef C<MyT> C_MyT;
int main(int argc, char** argv) {
V* o2 = C_MyT::new_();
assert(dynamic_cast<C_MyT*> (o2)); // failure in GCC, success in CLang
return 0;
}

g++ appears to be behaving correctly. See Dynamic downcast on private inheritance within private scope which has a good answer describing this.

Related

Instance of C++ template class as a member of another template class

Let's say I have following templated C++ class
#include <cstdint>
template <uint32_t NO_POINTS>
class A
{
public:
struct Point
{
float x;
float y;
};
A(const Point (&points)[NO_POINTS])
{
for (uint32_t point = 0; point < NO_POINTS; point++) {
table[point] = points[point];
}
}
private:
Point table[NO_POINTS];
};
and I would like to use an instance of this class as a private member of the following class:
#include "A.h"
template <uint32_t NO_LUT_POINTS>
class B
{
public:
B(A<NO_LUT_POINTS>::Point (&table)[NO_LUT_POINTS]) : lut(table){}
private:
A<NO_LUT_POINTS> lut;
};
#include "B.h"
int main(int argc, char** argv) {
B<4> foo({{1326.0, 25.0}, {1601.0, 30.0}, {1922.0, 35.0}, {2293.0, 40.0}});
return 0;
}
I have attempted to compile this code but the compiler reports following error
A<NO_LUT_POINTS>::Point is not a type. I don't understand what the reason for this error is. Can anybody explain to me why the compiler reports this error?
This is a common mistake with types nested in template classes. You need to add typename to tell the compiler that Point is a type.
...
public:
B(typename A<NO_LUT_POINTS>::Point const (&table)[NO_LUT_POINTS]) : lut(table){}
...
Beyond solving your problem, however, please notice that Point doesn't depend on the template parameters of A, so you should not nest it in that class. This would remove the necessity for adding typename.

Getting function pointer of private member function in C++

Is there a way to get function pointer for a member function that is private inside a class
class A
{
public:
void callMe()
{
cout<<__FUNCTION__<<endl;
}
private:
void fooMem()
{
cout<<__FUNCTION__<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
auto fp = &A::fooMem;
return 0;
}
Compiling this in vs 2012 c++ compiler causes below error
error C2248: 'A::fooMem' : cannot access private member declared in class 'A'
see declaration of 'A::fooMem'
I looked into a amazing solution to a similar problem (though I am not very clear how this actually works, if someone can explain that would be great too), Here I want the address of the member not to invoke it.
The reason I am asking for the address is I'll be patching this function with a different implementation.
The class as such is not modifiable, But I can inherit if that can help achieve this.
Since you cannot modify the original class, it would be much easier to simply inherit the class and create a duplicate of the function in a public memberspace.
I tried this out and it works as expected, at least with g++:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
class A
{
public:
void aFunction()
{
cout<<"This is aFunction"<<endl;
}
private:
void anotherFunction()
{
cout<<"This is anotherFunction"<<endl;
}
};
class B: public A
{
public:
void anotherFunction()
{
cout<<"This is also anotherFunction, but it's accessible!"<<endl;
}
};
int main(int argc, char* argv[])
{
A firstClass;
B coach;
firstClass.aFunction();
coach.anotherFunction();
return 0;
}
When I run this code I get the following output:
$ ./a.out
This is aFunction
This is also anotherFunction, but it's accessible!
Proving the compiler understood which version of anotherFunction to use.

Error while inheriting std::vector

I am trying to define an inherited class from std::vector class. Below is the code
template<class t>
class Vector:vector<t>
{
public:
using vector<t>::vector;
};
int main(int argc, char *argv[])
{
Vector<int> v;
return 0;
}
And I am getting error like this:
"error: 'std::vector<t, std::allocator<_CharT> >::vector' names constructor"
So basically I would like to know why my program is failing and what all procedures to be overloaded in the my inherited class from parent std::vector class.
Thanks in advance.
I tried:
#include <vector>
template<class t>
class Vector: std::vector<t>
{
public:
using std::vector<t>::vector;
};
int main()
{
Vector<int> v;
return 0;
}
and it works fine on gcc 4.8. when passing the flag -std=c++11.
It sounds like your compiler cannot figure out what are you trying to accomplish with that using directive. Since inheriting constructors is a C++11 feature, I suggest you make sure that you are running your compiler in C++11 mode.

Struct inheritance: implicitly public or private?

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?
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.
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.

Instantiation of template static member variable

I’m trying to puzzle out how clang determines what C++ template static member variables require instantiation, and I’m seeing some behavior that has me confused.
Given the following code:
#include <stdio.h>
#include <typeinfo>
int report(const char *name)
{
printf("Reporting class: %s\n", name);
return 0;
}
template<typename ReportedClass>
class reported_class
{
public:
reported_class()
{
_reported_instances++;
}
private:
static int _reported_instances;
};
template<typename ReportedClass>
int reported_class<ReportedClass>::_reported_instances = report(typeid(ReportedClass).name());
class foo : reported_class<foo>
{
public:
int baz() { return 0; }
};
class bar : reported_class<bar>
{
public:
bar() { }
int baz() { return 0; }
};
int main(int argc, char **argv)
{
return 0;
}
When I run it, I see the following:
$ c++ -v
Apple LLVM version 5.0 (clang-500.0.68) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
$ c++ test.cpp
$ ./a.out
Reporting class: 3bar
$
Why is the static for reported_class being instantiated, but not the one for foo? The only difference appears to be the presence of a constructor, but I’d expect the reported_class constructor to be called in either case (therefore forcing static instantiation due to use in the constructor). Is there a reason for this in the standard that I’m not aware of, and is this something that can be relied upon?
gcc-4.7.3 displays the same behavior, so I assume that this is something that I"m misunderstanding.
Apparently in the not shown main function you're not instantiating either class.
Then there's no reason for the compiler to generate a default constructor for class foo.
And without that, there's no code that instantiates reported_class<foo>.