This question already has answers here:
Injected class name compiler discrepancy
(3 answers)
Closed 6 years ago.
namespace fooo {
class Fooo {
public:
int a;
};
}
namespace fooo {
class Test {
public:
Test(Fooo::Fooo *i) {
i->a = 1;
}
};
}
This code compiles fine with clang (any version) but fails with gcc.
Can anyone explain why?
EDIT:
Yes, I know the issue here is kinda obvious but why does clang accept it? The person who told me this said that this is a bug in the standard and that there is a Defect Report. Can anyone point to the actual DR?
The error message from gcc tells you exactly what the problem is:
t.cpp:11:16: error: ‘fooo::Fooo::Fooo’ names the constructor, not the type
Test(const Fooo::Fooo *i) {
^
it is suprising that clang doesn't give an error.
Related
This question already has answers here:
Can a method be referenced using a child class name in C++?
(2 answers)
Closed 6 months ago.
godbot
While doing some C++ templates coding, I came accross something that compiles for Clang but failed for GCC, it's like something below:
#include <iostream>
struct B {
virtual void foo() {
std::cout << "B::foo" << std::endl;
}
};
struct D:B {
};
int main(int argc, char* argv[]) {
D* d = new D();
static_cast<B*>(d)->D::foo();
delete d;
}
I want to know if the behavior of the code above well-defined according to C++ standard?
GCC is correct in this case, the program is ill formed. You cannot call a method of D from an instance of B directly without casting (in other words, undoing your initial upcast).
https://godbolt.org/z/b43zcWMqe
Both Clang and GCC should emit something to the effect of
<source>:14:26: error: 'D' is not a base of 'B'
14 | static_cast<B*>(d)->D::foo();
This question already has an answer here:
get<string> for variants fail under clang++ but not g++
(1 answer)
Closed 4 years ago.
The following uses of std::visit compiles properly under gcc 7.2 but fails to compile under clang 5.0. Does anyone know what the problem is?
#include <variant>
struct S1 {int foo() { return 0; }};
struct S2 {int foo() { return 1; }};
using V = std::variant<S1, S2>;
int bar() {
V v;
return std::visit([](auto& s) { return s.foo(); }, v);
}
The first error is this:
include/c++/7.2.0/variant:238:46: error: cannot cast 'std::variant<S1, S2>' to its private base class
'std::__detail::__variant::_Variant_storage<true, S1, S2>'
return __get(std::in_place_index<_Np>, std::forward<_Variant>(__v)._M_u);
Here is a link to godbolt shows this error: https://godbolt.org/g/5iaKUm
This is known bug 33222 that seems to only affect libstdc++'s std::variant (and other constructs using the same combination). The problem is related to friend function to templates - see the thread for more detail.
The variant from libc++ doesn't seem to use the technique of friends that libstdc++ used, so you might want to temporarily change to libc++ in the meantime.
Small update: This has been fixed in the latest trunk.
This question already has answers here:
Why doesn't ADL find function templates?
(4 answers)
Closed 9 years ago.
Could someone please explain why the following code is giving error (error C2065: 'select' : undeclared identifier) at compile time:
namespace N {
class MyClass{
};
template<int I> void select(MyClass*)
{}
}
void g (N::MyClass* mp)
{
select<10>(mp);
}
void main()
{}
According to Argument Dependent Lookup, this should work fine, since I have specified N:: in `g``s argument. So, select should be visible to compiler.
Why does ADL not work here?
have you tried N::select?
either that or a
using namespace N
should work since simply select is not visible
Any time you utilise a class from a divergent namespace from the one you are currently in you must either reference it directly (N::select) or set up a using namespace (using namespace N;) or set up a direct using statement to it for future use (using N::select)
For disambiguation I would look at this and this , which between them should give you a good start on how/why you cannot simply call select.
Cheers, and feel free to get a hold of me for more info.
This question already has answers here:
Why is there no call to the constructor? [duplicate]
(3 answers)
Closed 8 years ago.
I am using Code::Blocks 10.05 with GCC on Windows 7. I was experimenting with C++ constructors and I compiled and executed the following program.
#include<iostream>
using namespace std;
class base {
public:
base() {
cout<<"\n Constructor Invoked\n";
}
};
int main() {
base ob;
return 0;
}
The output was as expected and shown below.
Constructor Invoked
But while typing the program I accidentally compiled the following program. To my surprise it compiled without any error or warning.
#include<iostream>
using namespace std;
class base {
public:
base() {
cout<<"\n Constructor Invoked\n";
}
};
int main() {
base ob();
return 0;
}
But the program didn't give any output, just a blank screen. But no error or warning. Since it hasn't called the constructor I assume no object was created. But why no error or warning? Am I missing something very obvious?
When I added the line cout<<sizeof(ob); I got the following error message.
error: ISO C++ forbids applying 'sizeof' to an expression of function type
So what is ob? Is it considered as a function or an object?
Please somebody explain the line of code base ob(); and what actually happens in the memory when that line of code is executed?
Thank you.
You have declared a function with
base ob();
It will do nothing.
See here
This question already has answers here:
rvalue to lvalue conversion Visual Studio
(3 answers)
Closed 9 years ago.
#include<iostream>
struct Foo
{
};
void func(Foo& f)
{
std::cout << "foo" ;
}
int main()
{
func(Foo());//ok compile
std::cin.ignore();
return 1;
}
the standard doesn't say this king of thing is not legal ? Is it a bug ?
It shouldn't be legal. But some older version of Visual C++ (for instance VC6) allow it, afaik.