#include <map>
#include <memory>
#include <iostream>
using namespace std;
class test
{
public:
test(){}
~test(){}
enum type
{
error = 0
};
private:
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();//build error
//shared_ptr<map<type, int>> member_ = make_shared<map<type, int>>();//build ok
};
int main()
{
return 0;
}
when i compile program with "shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>()"
main.cpp:17:63: error: expected ‘;’ at end of member declaration
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();
^
main.cpp:17:67: error: expected unqualified-id before ‘>>’ token
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();
^
main.cpp:17:58: error: wrong number of template arguments (1, should be at least 2)
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();
^
In file included from /usr/include/c++/5/map:61:0,
from main.cpp:1:
/usr/include/c++/5/bits/stl_map.h:96:11: note: provided for ‘template<class _Key, class _Tp, class _Compare, class _Alloc> class std::map’
class map
^
main.cpp:17:42: error: parse error in template argument list
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();
^
main.cpp:17:42: error: cannot resolve overloaded function ‘make_shared’ based on conversion to type ‘std::shared_ptr<std::map<int, test::type> >’
Have tried your code with Online C++ Compiler, got the same errors with C++, C++11, and C++14 compatible compilers, but got compiled well with C++17 compatible compiler. This means that your code is not legal in C++ standards prior to C++17. As pointed out by others, the code, however, compiled well on other online compiler sites even with C++11 and C++14 standards. So I would guess the errors are due to supported / unsupported features of compilers.
Well, you are not supposed to initialize class members like this anyway. The initialization of class members should happen in the class constructor, like so:
#include <map>
#include <memory>
#include <iostream>
using namespace std;
class test
{
public:
test() { member_ = make_shared<map<int, type>>(); }
~test() { }
enum type
{
error = 0
};
private:
shared_ptr<map<int, type>> member_;
};
int main()
{
return 0;
}
This compiles fine even in Online C++ Compiler which is the only place we are managing to reproduce the problem.
Related
A simple program as below, no c++11 syntax at all (e.cpp)
#include<iostream>
using namespace std;
namespace m{
class my{
public:
enum A{
u=1,
v=2,
w=3
};
static A f(A a){
return (A)(a + A::u);
}
};
int main(){
using namespace m;
my::A r=my::f(my::u);
return 0;
}
Using g++4.1.2 to compile it:
e.cpp:17:2: warning: no newline at end of file
e.cpp: In static member function ‘static m::my::A m::my::f(m::my::A)’:
e.cpp:11: error: expected primary-expression before ‘)’ token
e.cpp:11: error: ‘A’ is not a class or namespace
Using g++4.9.2 with -std=c++98
g++ e.cpp -std=c++98
e.cpp: In static member function ‘static m::my::A m::my::f(m::my::A)’:
e.cpp:11:36: error: ‘A’ is not a class or namespace
static A f(A a){return (A)(a + A::u);}
^
But using -std=c++11 is ok:
g++ e.cpp -std=c++11
To make it compile using c++98, I change it to avoid "A::" to be:
static A f(A a){return (A)(a + u);}
So seems that under c++98, the embeded enum class is not recognized inside a class, while in c++11 it works. Is this a difference in enum resolution, or some previous syntax bug in c++98 standard?
Enum values are not scoped by the enum type (either in C++98 or C++11). In the following example:
namespace N {
enum E { X };
}
X is directly in the scope of namespace N. Its fully qualified identifier would be ::N::X.
This behaviour was changed by C++11, where following the same definition, the identifier of X can also be referred using ::N::E::X:
[dcl.enum/11]
An enumerator declared in class scope can be referred to using the class member access
operators (::, . (dot) and -> (arrow)), see 5.2.5. [ Example:
struct X {
enum direction { left=’l’, right=’r’ };
int f(int i) { return i==left ? 0 : i==right ? 1 : 2; }
};
void g(X* p) {
direction d; // error: direction not in scope
int i;
i = p->f(left); // error: left not in scope
i = p->f(X::right); // OK
i = p->f(p->left); // OK
// ...
}
—end example ]
The enumeration name could not be used to qualify an enumerator prior to C++11. So there is no bug in C++98 mode, the code is just ill-formed.
You are correct in deducing the rules have changed.
The C++ FAQ lists the changes made to enumerations in C++11, and cites the proposals that drove those changes.
Hello I know that to declare a std::vector I have to do like this
std::vector<double> a(0);
But in my file it does not work. Here is my code :
main.cpp :
#include "test.hpp"
int main()
{
Test test;
return EXIT_SUCCESS;
}
test.hpp :
#ifndef DEF_TEST
#define DEF_TEST
#include <iostream>
#include <vector>
class Test
{
public:
Test();
private:
std::vector<double> a(0);
};
#endif
and this is test.cpp :
#include "test.hpp"
Test::Test()
{
a.push_back(2.3);
std::cout << a[0] << std::endl;
}
And the compiler told me :
In file included from main.cpp:1:0:
test.hpp:11:23: error: expected identifier before numeric constant
std::vector<double> a(0);
^
test.hpp:11:23: error: expected ‘,’ or ‘...’ before numeric constant
In file included from test.cpp:1:0:
test.hpp:11:23: error: expected identifier before numeric constant
std::vector<double> a(0);
^
test.hpp:11:23: error: expected ‘,’ or ‘...’ before numeric constant
test.cpp: In constructor ‘Test::Test()’:
test.cpp:5:1: error: ‘((Test*)this)->Test::a’ does not have class type
a.push_back(2.3);
^
test.cpp:6:17: error: invalid types ‘<unresolved overloaded function type>[int]’ for array subscript
std::cout << a[0] << std::endl;
Thank you for your help !
It seems to me that you can not use a constructor for a member declaration of a class; to use constructors for the vector in a class you must specify it in a constructor for the class, e.g.
class Test {
private:
vector<double> a;
public:
Test() : a(0) {;}
};
You can initialize a variable using the following syntax:
std::vector<double> a(0);
but you can't use that for in-class initialization of class members. To initialize a member in-class, you can use the following syntax:
std::vector<double> a = {};
std::vector members will get initialized by the default initializer once an instance of your class is created.
If you want to call the vector initializer explicitly you can do it this way in your Test.cpp file:
Test::Test():
a(0) {
//...
}
Ps. An advantage of this is that you also can initialize constants that are members of your class.
You must do the following to initialize the vector as a class member:
class Test{
public:
Test();
private:
std::vector<double> a = std::vector<double>(0);
};
FYI, this code sizes the vector to 0, which is redundant. You can simply write std::vector<double> a and its size will be 0 to begin with. In other cases, if you want the vector to be of size n, then you use the method I've written with n instead of 0.
You can use an initialiser list for this after your constructer
Test::Test() : a(0)
{
...
}
You need to remove the (0) from your .hpp file.
Although there is at least one similar question, I still ask mine since that one hasn't got solved and seems more complicated. I'm trying to simplify mine.
I have a .cpp file that uses .h as below, and compiling these sheds error as follows. Any idea is appreciated. Note that codes are simplified in order to minimally show the problematic parts only.
FC_boost_prove.h:
#ifndef FC_H
#define FC_H
#include <vector>
#include "iostream"
#include "boost/signal.hpp"
#include "boost/bind.hpp"
#include <boost/random.hpp>
typedef boost::signal0<void()> PreUpdateSignal;
typedef PreUpdateSignal::slot_function_type PreUpdateSlot;
typedef boost::signal0<void()> PostUpdateSignal;
typedef PostUpdateSignal::slot_function_type PostUpdateSlot;
class FC {
public:
FC(uint width, uint height) {
std::cout << "In constructor." << std::endl;
}
~FC() {
//Do ...
}
void connectPreUpdate(PreUpdateSlot s) {
preUpdateSignal_.connect(s);
}
void connectPostUpdate(PostUpdateSlot s) {
postUpdateSignal_.connect(s);
}
protected:
PreUpdateSignal preUpdateSignal_;
PostUpdateSignal postUpdateSignal_;
};
#endif
FC_boost_prove.cpp:
#include <iostream>
#include <string>
#include "FC_boost_prove.h"
int main() {
std::cout << "test." << std::endl;
}
Compile error:
$ g++ FC_boost_prove.cpp
In file included from /usr/include/boost/signals/signal_template.hpp:22,
from /usr/include/boost/signals/signal0.hpp:24,
from /usr/include/boost/signal.hpp:19,
from FC_boost_prove.h:7,
from FC_boost_prove.cpp:3:
/usr/include/boost/last_value.hpp: In instantiation of ‘boost::last_value<void()>’:
/usr/include/boost/signals/signal_template.hpp:178: instantiated from ‘boost::signal0<void(), boost::last_value<void()>, int, std::less<int>, boost::function0<void()> >’
FC_boost_prove.h:12: instantiated from here
/usr/include/boost/last_value.hpp:22: error: function returning a function
In file included from /usr/include/boost/signals/signal0.hpp:24,
from /usr/include/boost/signal.hpp:19,
from FC_boost_prove.h:7,
from FC_boost_prove.cpp:3:
/usr/include/boost/signals/signal_template.hpp: In instantiation of ‘boost::signal0<void(), boost::last_value<void()>, int, std::less<int>, boost::function0<void()> >’:
FC_boost_prove.h:12: instantiated from here
/usr/include/boost/signals/signal_template.hpp:330: error: function returning a function
/usr/include/boost/signals/signal_template.hpp:370: error: function returning a function
In file included from /usr/include/boost/function/detail/maybe_include.hpp:13,
from /usr/include/boost/function/function0.hpp:11,
from /usr/include/boost/signals/signal_template.hpp:38,
from /usr/include/boost/signals/signal0.hpp:24,
from /usr/include/boost/signal.hpp:19,
from FC_boost_prove.h:7,
from FC_boost_prove.cpp:3:
/usr/include/boost/function/function_template.hpp: In instantiation of ‘boost::function0<void()>’:
FC_boost_prove.h:24: instantiated from here
/usr/include/boost/function/function_template.hpp:1006: error: function returning a function
/usr/include/boost/function/function_template.hpp: In instantiation of ‘boost::detail::function::basic_vtable0<void()>’:
/usr/include/boost/function/function_template.hpp:856: instantiated from ‘void boost::function0<R>::clear() [with R = void()]’
/usr/include/boost/function/function_template.hpp:752: instantiated from ‘boost::function0<R>::~function0() [with R = void()]’
/usr/include/boost/signals/slot.hpp:105: instantiated from here
/usr/include/boost/function/function_template.hpp:486: error: function returning a function
/usr/include/boost/function/function_template.hpp:643: error: function returning a function
Environment: Ubuntu 10.10, g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
Why are you specifying boost::signal0<>? The signalN templates are for deficient compilers that can't properly parse function signatures.
Either use signal and specify the function signature, as recommended for modern compilers:
typedef boost::signal<void()> PreUpdateSignal;
typedef boost::signal<void()> PostUpdateSignal;
or use signalN and specify the return type (and every argument type) explicitly, as needed for deficient compilers:
typedef boost::signal0<void> PreUpdateSignal;
typedef boost::signal0<void> PostUpdateSignal;
I want to iterate over a QMultiMap using
QMultiMap<double, TSortable>::const_iterator it;`
but the compiler complains
error: expected ‘;’ before ‘it’
resulting in a
error: ‘it’ was not declared in this scope
for every usage. I tried ConstIterator, const_iterator and even the slower Iterator without any success. Is it even possible to use Q(Multi)Map with a template class? Why can't I declare an Iterator when definition (as void*) is ok?
I use the following code (include guard omitted):
#include <QtCore/QDebug>
#include <QtCore/QMap>
#include <QtCore/QMultiMap>
#include <limits>
/** TSortable has to implement minDistance() and maxDistance() */
template<class TSortable>
class PriorityQueue {
public:
PriorityQueue(int limitTopCount)
: limitTopCount_(limitTopCount), actMaxLimit_(std::numeric_limits<double>::max())
{
}
virtual ~PriorityQueue(){}
private:
void updateActMaxLimit(){
if(maxMap_.count() < limitTopCount_){
// if there are not enogh members, there is no upper limit for insert
actMaxLimit_ = std::numeric_limits<double>::max();
return;
}
// determine new max limit
QMultiMap<double, TSortable>::const_iterator it;
it = maxMap_.constBegin();
int act = 0;
while(act!=limitTopCount_){
++it;// forward to kMax
}
actMaxLimit_ = it.key();
}
const int limitTopCount_;
double actMaxLimit_;
QMultiMap<double, TSortable> maxMap_;// key=maxDistance
};
GCC gives this error before the one you quoted:
error: need ‘typename’ before ‘QMultiMap<double, TSortable>::const_iterator’ because ‘QMultiMap<double, TSortable>’ is a dependent scope
which explains the problem. Add the typename keyword:
typename QMultiMap<double, TSortable>::const_iterator it;
and it will build.
I would like to use boost's multi-index container with a class hierarchy. Is this possible?
If I try:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
using namespace ::boost;
using namespace ::boost::multi_index;
class A{
public:
int m;
A(int p = 0){m = p;};
};
class B: public A{
public:
int n;
B(int p = 0, int q = 0): A(p){ n = q;};
};
typedef multi_index_container<
B,
indexed_by<
ordered_unique<identity<B> >,
ordered_non_unique<member<B, int, &B::m> >
>
> mindex;
int main(void){
return 0;
}
I get the following errors:
multiindextest.cpp:25: error: could not convert template argument ‘&A::m’ to ‘int B::*’
multiindextest.cpp:25: error: template argument 1 is invalid
multiindextest.cpp:26: error: template argument 2 is invalid
multiindextest.cpp:27: error: template argument 2 is invalid
multiindextest.cpp:27: error: invalid type in declaration before ‘;’ token
If I change line 25 to:
ordered_non_unique<member<B, int, &B::n> >
It compiles fine. Any help would be much appreciated. Thanks.
I'm not quite sure, if this is what you are looking for, but you can change line 25 to:
ordered_non_unique<member<A, int, &A::m> >
This is compiling on gcc 4.4.
Regards Lars.