This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Error calling template method in “templated-base-class”
The following code compiles with MSVC10 but not with gcc 4.2.1:
template<class BaseQNativeWindow>
class NativeWindow : public BaseQNativeWindow
{
public:
NativeWindow(AIPanelPlatformWindow handle) : BaseQNativeWindow(handle)
{}
protected:
virtual void closeEvent(QCloseEvent *e)
{
QList<QWidget *> childrenList;
childrenList = BaseQNativeWindow::findChildren< QWidget * >(); // GCC ERROR
foreach(QWidget *child, childrenList)
{
child->close();
}
}
};
This is what gcc complains about:
error: expected primary-expression before ‘*’ token
error: expected primary-expression before ‘>’ token
error: expected primary-expression before ‘)’ token
findChildren is a templated method that BaseQNativeWindow must provide. It seems that gcc assumes that findChildren is not a template even before knowing what type BaseQNativeWiindow is. Can anyone explain this?
Thanks.
You have to say:
BaseQNativeWindow::template findChildren< QWidget * >()
// ^^^^^^^^
Since findChildren is a dependent name, its meaning must be disambiguated.
Related
There is a class library (I cannot/should not change) defined in MIDI.h:
template<class SerialPort, class _Settings = DefaultSettings>
class MidiInterface
{
...
I want to use this class as argument.
Question question is a duplicate, however I still get a compilation error.
My own header class file looks like:
#include <MIDI.h>
class M
{
public:
void setup();
void run();
private:
void printMessage(const MidiInterface<SerialPort, _Settings>&
midiInterface);
};
I get the following errors:
In file included from sketch\M.cpp:1:0:
M.h:10: error: 'MidiInterface' does not name a type
void printMessage(const MidiInterface<SerialPort, _Settings>& midiInterface);
^
M.h:10: error: expected ',' or '...' before '<' token
void printMessage(const MidiInterface<SerialPort, _Settings>& midiInterface);
^
exit status 1
'MidiInterface' does not name a type
How can I change the code so it compiles?
It looks like MIDI.h in this code puts everything in a namespace. If that's what you're using, try MIDI_NAMESPACE::MidiInterface<SerialPort, _Settings>.
I have some c++ code that will compile fine in Visual Studio 2013 but will not compile in linux using g++ (no IDE).
What is causing the difference and how can I make the code compile on linux? Is it because they are different compilers? Do I need a specific compiler setting?
Code:
#include <iostream>
typedef class IApp;
typedef class Component;
class Component
{
public:
protected:
IApp* app;
template<typename T>
void registerEvent()
{
app->logEvent();
}
};
class IApp : protected Component
{
public:
static IApp NULL_APP;
void logEvent()
{
printf("Event Logged\n");
}
protected:
virtual void foo() = 0;
};
int main(int argc, char** argv)
{
printf("Alive\n");
system("pause");
return 0;
}
On windows I get no compiler errors. On linux I get the following compiler errors:
g++ - o res main.cpp - std = c++11
main.cpp:3 : 15 : warning : ‘typedef’ was ignored in this declaration[enabled by default]
typedef class IApp;
^
main.cpp:4 : 15 : warning : ‘typedef’ was ignored in this declaration[enabled by default]
typedef class Component;
^
main.cpp: In member function ‘void Component::registerEvent()’ :
main.cpp : 16 : 6 : error : invalid use of incomplete type ‘class IApp’
app->logEvent();
^
main.cpp:3 : 15 : error : forward declaration of ‘class IApp’
typedef class IApp;
^
main.cpp: At global scope :
main.cpp : 23 : 14 : error : cannot declare variable ‘IApp::NULL_APP’ to be of abstract type ‘IApp’
static IApp NULL_APP;
^
main.cpp:20 : 7 : note : because the following virtual functions are pure within ‘IApp’ :
class IApp : protected Component
^
main.cpp : 31 : 15 : note : virtual void IApp::foo()
virtual void foo() = 0;
^
make: ***[all] Error 1
Here you should simply remove typedef:
typedef class IApp;
Then this template method should be defined out-of-line, below IApp:
template<typename T>
void registerEvent()
{
app->logEvent();
}
Otherwise, it doesn't see the declaration of IApp which it needs to dereference.
Finally, this does not make sense:
virtual void foo() = 0;
Because the same class has a static member of its own class type, so needs to instantiate it. But you've prevented that with a pure virtual function.
GCC is right not to compile this code.
Leave out the typedef keywords before the forward class declarations, they're not necessary. Just class MyClass; is sufficient for a forward declaration. The other issue is that foo() is pure virtual - you need to implement it if you want to instantiate the class. I'm surprised the Microsoft complier doesn't complain but then that's Microsoft.
I am a beginner of c++ meta programming.
Now I test a code which is on a text book.
The following code is a copy of the code but it give me an error message
at line(1). At line(1), it seems the code tries to call Layer2::function with template keyword because it is following another template. Unfortunately, my compiler give me an error message, "error: expected ‘;’ before ‘::’ token.". Can anyone find a problem of the code?
Thank you very much.
template<typename T>
class Layer0 {
public:
template<int L1>
class Layer1 {
public:
template<int L2>
class Layer2 {
public:
virtual void function(void);
};
};
};
template<typename T, int L1>
class LayerTest {
public:
void pointer (typename Layer0<T>::template Layer1<L1>::template Layer2<L1>* ptr) {
// At the following line(1), I got an error message, error: expected ‘;’ before ‘::’ token.
ptr->template Layer2<L1>::function(); // (1) inhibit call of virtual function
}
};
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I´ve browsed other similar topics and did not find an answer to my problem...
The code below illustrates the situation. A Base class and a Derived class:
Base.hpp
namespace test {
template<class T>
class Base {
public:
Base();
virtual ~Base();
};
}
Base.cpp
#include "Base.hpp"
namespace test {
template<class T>
Base<T>::Base() {
// TODO Auto-generated constructor stub
};
template<class T>
Base<T>::~Base() {
// TODO Auto-generated destructor stub
};
}
Derived.hpp
namespace test {
class Derived : public Base<int> {
public:
Derived();
virtual ~Derived();
};
} /* namespace aeirtuaccess */
Derived.cpp
#include "Derived.hpp"
namespace test {
Derived::Derived() {
// TODO Auto-generated constructor stub
};
Derived::~Derived() {
// TODO Auto-generated destructor stub
};
}
When I compile this code with Coliru - see it in action here, it works fine, but when I go to my Ubuntu environment using g++ I´m having the following error:
>g++ Base.cpp Derived.cppIn file included from Derived.cpp:2:0:
Derived.hpp:3:28: error: expected template-name before ‘<’ token
class Derived : public Base<int> {
^
Derived.hpp:3:28: error: expected ‘{’ before ‘<’ token
Derived.hpp:3:28: error: expected unqualified-id before ‘<’ token
Derived.cpp:6:18: error: invalid use of incomplete type ‘class test::Derived’
Derived::Derived() {
^
In file included from Derived.cpp:2:0:
Derived.hpp:3:7: error: forward declaration of ‘class test::Derived’
class Derived : public Base<int> {
^
Derived.cpp:11:19: error: invalid use of incomplete type ‘class test::Derived’
Derived::~Derived() {
^
In file included from Derived.cpp:2:0:
Derived.hpp:3:7: error: forward declaration of ‘class test::Derived’
class Derived : public Base<int> {
Is there any difference between the compilers ? Should I use a specific g++ flag or version ? Is there something else that I need to do to fix that in my Ubuntu environment ?
In Derived.hpp, you need to add:
#include "Base.hpp"
at the top. Otherwise, the compiler doesn't know what Base refers to when compiling this file.
I find one of the most time-consuming compiler errors for me is "cannot instantiate abstract class," since the problem is always that I didn't intend for the class to be abstract and the compiler doesn't list which functions are abstract. There's got to be a more intelligent way to solve these than reading the headers 10 times until I finally notice a missing "const" somewhere. How do you solve these?
cannot instantiate abstract class
Based on this error, my guess is that you are using Visual Studio (since that's what Visual C++ says when you try to instantiate an abstract class).
Look at the Visual Studio Output window (View => Output); the output should include a statement after the error stating:
stubby.cpp(10) : error C2259: 'bar' : cannot instantiate abstract class
due to following members:
'void foo::x(void) const' : is abstract
stubby.cpp(2) : see declaration of 'foo::x'
(That is the error given for bdonlan's example code)
In Visual Studio, the "Error List" window only displays the first line of an error message.
C++ tells you exactly which functions are abstract, and where they are declared:
class foo {
virtual void x() const = 0;
};
class bar : public foo {
virtual void x() { }
};
void test() {
new bar;
}
test.cpp: In function ‘void test()’:
test.cpp:10: error: cannot allocate an object of abstract type ‘bar’
test.cpp:5: note: because the following virtual functions are pure within ‘bar’:
test.cpp:2: note: virtual void foo::x() const
So perhaps try compiling your code with C++, or specify your compiler so others can give useful suggestions for your specific compiler.
C++Builder tells you which method is abstract:
class foo {
virtual void x() const = 0;
};
class bar : public foo {
virtual void x() { }
};
new bar;
[BCC32 Error] File55.cpp(20): E2352 Cannot create instance of abstract class 'bar'
[BCC32 Error] File55.cpp(20): E2353 Class 'bar' is abstract because of 'foo::x() const = 0'