I tried to compile flann by uses Make method from pack of another codes but I got this error about protected functions in one of the flann binary files './flann/util/matrix.h:75'
Can any one help me to fix this error?
I'm really new in programming, plz be simple as u can! :P
g++ -I. -Iflann/src/cpp -c -o src/main.o src/main.cpp
In file included from ./boost/asio/async_result.hpp:18,
from ./boost/asio.hpp:20,
from src/common.hpp:30,
from src/main.cpp:9:
./boost/asio/detail/config.hpp:367:5: warning: #warning Please define _WIN32_WIN NT or _WIN32_WINDOWS appropriately.
./boost/asio/detail/config.hpp:368:5: warning: #warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line.
./boost/asio/detail/config.hpp:369:5: warning: #warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
./flann/util/matrix.h: In function 'int cbir::main(int, char**)':
./flann/util/matrix.h:75: error: 'flann::uchar* flann::Matrix_::data' is protected
src/main.cpp:39: error: within this context
Makefile:43: recipe for target `src/main.o' failed
make: *** [src/main.o] Error 1
This is matrix.h :
#ifndef FLANN_DATASET_H_
#define FLANN_DATASET_H_
#include "flann/general.h"
#include <stdio.h>
namespace flann
{
typedef unsigned char uchar;
class Matrix_
{
public:
Matrix_() : rows(0), cols(0), stride(0), data(NULL)
{
};
Matrix_(void* data_, size_t rows_, size_t cols_, flann_datatype_t type, size_t stride_ = 0) :
rows(rows_), cols(cols_), stride(stride_)
{
data = static_cast<uchar*>(data_);
if (stride==0) stride = flann_datatype_size(type)*cols;
}
inline void* operator[](size_t index) const
{
return data+index*stride;
}
void* ptr() const
{
return data;
}
size_t rows;
size_t cols;
size_t stride;
flann_datatype_t type;
protected:
uchar* data;
};
template <typename T>
class Matrix : public Matrix_
{
public:
typedef T type;
Matrix() : Matrix_()
{
}
Matrix(T* data_, size_t rows_, size_t cols_, size_t stride_ = 0) :
Matrix_(data_, rows_, cols_, flann_datatype<T>::value, stride_)
{
}
FLANN_DEPRECATED void free()
{
fprintf(stderr, "The flann::Matrix<T>::free() method is deprecated "
"and it does not do any memory deallocation any more. You are"
"responsible for deallocating the matrix memory (by doing"
"'delete[] matrix.ptr()' for example)");
}
inline T* operator[](size_t index) const
{
return reinterpret_cast<T*>(static_cast<uchar*>(Matrix_::data)+index*stride);
// return (T*)(Matrix_::operator [](index));
}
T* ptr() const
{
return reinterpret_cast<T*>(Matrix_::data);
}
};
}
#endif //FLANN_DATASET_H_
You should be using Matrix<T> instead of the untyped Matrix_ class. Then you can use ptr to get a typed pointer to the data, or the [] operator to get access to a specific element.
Related
main.cpp :
#include "timer.hpp"
int main() {
TCC_TIMER<0> speed_timer;
TC_TIMER<3, TIMER_16BIT> update_timer;
speed_timer = TCC_TIMER<0>::Instance();
update_timer = TC_TIMER<3, TIMER_16BIT>::Instance();
for(;;);
}
timer.hpp :
#ifndef TIMER_HPP
#define TIMER_HPP
class TIMER_GENERAL {
protected:
TIMER_GENERAL() : initialized(false) {};
~TIMER_GENERAL() {};
inline void Init(int number) {
timer_number = number;
initialized = true;
}
inline bool Initialized(void) {
return initialized;
}
bool initialized;
int timer_number;
};
class TIMER_16BIT : public TIMER_GENERAL {
protected:
};
template <class T>
class TIMER_TC : public T {
protected:
};
class TIMER_TCC : public TIMER_GENERAL {
public:
};
template <int number, class T>
class TC_TIMER : public TIMER_TC<T> {
public:
static TC_TIMER<number, T>& Instance(void) {
static TC_TIMER<number, T> timer;
if(!timer.initialized) {
timer.Init(number);
}
return timer;
}
};
template <int number>
class TCC_TIMER : public TIMER_TCC {
public:
static TCC_TIMER<number>& Instance(void) {
static TCC_TIMER<number> timer;
if(!timer.initialized) {
timer.Init(number);
}
return timer;
}
};
#endif /* TIMER_HPP */
When I compile this code with g++ 7.5.0:
g++ -O3 -Wall -std=c++17 main.cpp
I get a warning in the TCC_TIMER class:
dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]:
if(!timer.initialized) {
In TC_TIMER however, I do exactly the same and get no warning.
If I deliberately introduce an error by inserting:
timer = timer + 1;
just before the line with the warning, I get the error:
no match for 'operator+' (operand types are 'TCC_TIMER<0>' and 'int')
which indicates that the compiler knows that timer has the type TCC_TIMER<0>.
Also, when I explicitly cast timer to TCC_TIMER<0>:
if(!static_cast<TCC_TIMER<0>>(timer).initialized) {
the compiler is happy and the warning disappears.
If I use a function instead:
if(!timer.Initialized()) {
everything is ok too.
Can anyone explain why I get this warning in the TCC_TIMER class and not in the TC_TIMER class?
Can anyone explain why I do get this warning while the timer type seems to be ok?
My issue is simple. I am able to declare an overloaded function in the global namespace as a friend of a template class in a nested namespace using fundamental types, however if I change the definition and declaration of the function to return size_t, I get C2510 and C4430 errors. This only occurs with the return type of the function. size_t in the parameter list does not generate the issue. I have tried ::size_t, ::std::size_t, and std::size_t as well. Nothing seems to work. What is going on here and why?
I am using MS Visual Studio 2015
Thanks
UPDATED: Per comments I have included remaining code TestingApp.cpp. I also included stddef which does not solve the problem. With respect to the specific error messages I received, they are:
C2510 'size_t': left of '::' must be a class/struct/union TestingApp
pointer.h 41
C4430 missing type specifier - int assumed. Note: C++ does not support
default-int TestingApp pointer.h 41
Line 41 that does NOT generate compilation errors:
friend int ::fwrite<DATA_TYPE>(const Pointer<DATA_TYPE>& ptr, size_t count, FILE* stream);
Line 41 that DOES generate compilation errors:
friend size_t ::fwrite<DATA_TYPE>(const Pointer<DATA_TYPE>& ptr, size_t count, FILE* stream);
The following two files compile and run with no problem. However if I substitute int with size_t for the return type (and ONLY the return type keeping size_t as the second parameter of the function in either case) in the forward declaration, friend declaration, and definition, I get the errors indicated above.
/*******Begin Pointer.h******/
#pragma once
#include <cstdio>
namespace FW{
namespace Memory {
template <typename DATA_TYPE> class Pointer;
}
}
template <typename DATA_TYPE> inline
/* int works, size_t does not work */
int
/* size_t */
fwrite(const
FW::Memory::Pointer<DATA_TYPE>& ptr, size_t count, FILE* stream);
namespace FW{
namespace Memory{
template <typename DATA_TYPE> class Pointer {
/*Line 41*/ friend
/* int works, size_t does not work */
int
/* size_t */
::fwrite<DATA_TYPE>(const Pointer<DATA_TYPE>& ptr, size_t count, FILE* stream);
public:
/* Omitted for brevity */
private:
DATA_TYPE* m_pCurrent;
};
}
}
template <typename DATA_TYPE>
/* int works, size_t does not work */
int
/* size_t */
fwrite<DATA_TYPE>(const FW::Memory::Pointer<DATA_TYPE>& ptr, size_t count, FILE* stream) {
return fwrite(ptr.m_pCurrent, sizeof(DATA_TYPE), count, stream);
}
/*******End Pointer.h*******/
/*******Begin TestingApp.cpp******/
// TestingApp.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <cstdio>
#include <cstddef>
#include "..\DB\Pointer.h"
int main()
{
unsigned long* pData = new unsigned long[100];
for (size_t i = 0; i < 100; i++) {
pData[i] = i;
}
FW::Memory::Pointer<unsigned long> ptr(pData);
FILE* pFile = fopen("testFile", "wb");
if (pFile) {
fwrite(ptr, 10, pFile);
fclose(pFile);
}
delete[] pData;
pData = 0;
return 0;
}
/*****End TestingApp.cpp*****/
I searched through some of the other pages with this same error, but my code does not have any of their issues that I can find.
I have a base class named QBase defined in quadrature.h:
#ifndef SRC_QUADRATURE_H_
#define SRC_QUADRATURE_H_
#include "enum_order.h"
#include "enum_quadrature_type.h"
#include <vector>
#include <memory>
class QBase
{
protected:
QBase (const Order _order=INVALID_ORDER);
public:
virtual ~QBase() {}
virtual QuadratureType type() const = 0;
static std::unique_ptr<QBase> build (const QuadratureType qt, const Order order=INVALID_ORDER);
const std::vector<double> & get_points() const { return _points; }
const std::vector<double> & get_weights() const { return _weights; }
std::vector<double> & get_points() { return _points; }
std::vector<double> & get_weights() { return _weights; }
protected:
const Order _order;
std::vector<double> _points;
std::vector<double> _weights;
};
#endif /* SRC_QUADRATURE_H */
I derive a class QGaussLegendre by QBase definded in gauss_legendre.h
#ifndef SRC_QUADRATURE_GAUSSLEGENDRE_H_
#define SRC_QUADRATURE_GAUSSLEGENDRE_H_
#include "quadrature.h"
class QGaussLegendre : public QBase
{
public:
QGaussLegendre (const Order _order=INVALID_ORDER) : QBase (_order){}
~QGaussLegendre (){}
virtual QuadratureType type() { return QGAUSSLEGENDRE; }
};
#endif /* SRC_QUADRATURE_GAUSSLEGENDRE_H_ */
In the main file I use the build() member function to get points and weights as follows
const Order order = ddp.order;
const QuadratureType qt = ddp.qt;
static std::unique_ptr<QBase> qr(QBase::build(qt,order));
const std::vector<double>& points = qr->get_points();
const std::vector<double>& weights = qr->get_weights();
I don't have any problem till here. Now, the points and weights are defined in the file legendre_gauss.cxx
#include "gauss_legendre.h"
QGaussLegendre::QGaussLegendre(const Order order)
{
switch(order)
{
case CONSTANT:
case FIRST:
{
_points.resize (1);
_weights.resize(1);
_points[0](0) = 0.;
_weights[0]= 2.;
}
}
}
When I compile this last file I get the error:
/home/matteo/flux/gauss_legendre.cxx:13:1:
error: redefinition of ‘QGaussLegendre::QGaussLegendre(qenum::Order)’
QGaussLegendre::QGaussLegendre(const Order order)
^~~~~~~~~~~~~~
In file included from /home/matteo/flux/gauss_legendre.cxx:8:0:
/home/matteo/flux/gauss_legendre.h:25:3:
note: ‘QGaussLegendre::QGaussLegendre(qenum::Order)’ previously
defined here
QGaussLegendre (const Order _order=INVALID_ORDER) : QBase (_order)
^~~~~~~~~~~~~~
Can I do to solve the problem? Thanks a lot.
redefinition of classes error
That's not an error about redefinition of a class. That is an error about redefinition of a function. In particular, redefinition of the function QGaussLegendre::QGaussLegendre(const Order order) which is the contsructor of class QGaussLegendre.
You've defined it first here in quadrature.h:
QGaussLegendre (const Order _order=INVALID_ORDER) : QBase (_order){}
And second time in legendre_gauss.cxx:
QGaussLegendre::QGaussLegendre(const Order order)
{
Can I do to solve the problem?
Solution is to define the function exactly once.
I'm currently trying to learn templates in C++ and am unable to make sense of this current Error.
I was trying to write a sequence class based out of a code example from the book. I keep getting this error repeatedly.
I am required to write this template modularly. The functions work, but i can't find the source of the errors. I have tried changing name of .cpp file with no success.
This code is nearly identical to that which i found and ran in the book which compiled with no issues.
Here is my Code for header and implementation files.
#ifndef SEQUENCE_H
#define SEQUENCE_H
#include <cstdlib> // provides size_t
namespace CS3358_FA17_A04_sequenceOfNum
{
template <class Item>
class sequence
{
public:
// TYPEDEFS and MEMBER CONSTANTS
typedef Item value_type;
typedef size_t size_type;
static const size_type CAPACITY = 10;
// CONSTRUCTOR
sequence();
// MODIFICATION MEMBER FUNCTIONS
void start();
void end();
void advance();
void move_back();
void add(const Item& entry);
void remove_current();
// CONSTANT MEMBER FUNCTIONS
size_type size() const;
bool is_item() const;
Item current() const;
private:
Item data[CAPACITY];
size_type used;
size_type current_index;
};
}
#include "sequence.hpp"
.HPP File:
namespace CS3358_FA17_A04_sequenceOfNum
{
template <class Item>
sequence<Item>::sequence() : used(0), current_index(0) { }
template <class Item>
void sequence<Item>::start() { current_index = 0; }
template <class Item>
void sequence<Item>::end()
{
current_index = (used > 0) ? used - 1 : 0;
}
template <class Item>
void sequence<Item>::advance()
{
assert( is_item() );
++current_index;
}
template <class Item>
void sequence<Item>::move_back()
{
assert( is_item() );
if (current_index == 0)
current_index = used;
else
--current_index;
}
template <class Item>
void sequence<Item>::add(const Item& entry)
{
assert( size() < CAPACITY );
size_type i;
if ( ! is_item() )
{
if (used > 0)
for (i = used; i >= 1; --i)
data[i] = data[i - 1];
data[0] = entry;
current_index = 0;
}
else
{
++current_index;
for (i = used; i > current_index; --i)
data[i] = data[i - 1];
data[current_index] = entry;
}
++used;
}
template <class Item>
void sequence<Item>::remove_current()
{
assert( is_item() );
size_type i;
for (i = current_index + 1; i < used; ++i)
data[i - 1] = data[i];
--used;
}
template <class Item>
typename sequence<Item>::size_type sequence<Item>::size() const { return used;}
template <class Item>
bool sequence<Item>::is_item() const { return (current_index < used); }
template <class Item>
typename sequence<Item>::Item sequence<Item>::current() const
{
assert( is_item() );
return data[current_index];
}
}
Error's Are:
sequence does not name a type -> this occurs in every function
expected initializer before '<' every place a template specifier is used.
I have written many templates before, but i have always defined and implemented in the same file because of compiler and linker issues.
Any help would be much appreciated, here is a complete list of errors and their lines.
g++ -Wall -ansi -pedantic -c sequence.cpp
sequence.cpp:48:4: error: ‘sequence’ does not name a type
sequence<Item>::sequence() : used(0), current_index(0) { }
^
sequence.cpp:51:17: error: expected initializer before ‘<’ token
void sequence<Item>::start() { current_index = 0; }
^
sequence.cpp:54:17: error: expected initializer before ‘<’ token
void sequence<Item>::end()
^
sequence.cpp:60:17: error: expected initializer before ‘<’ token
void sequence<Item>::advance()
^
sequence.cpp:67:17: error: expected initializer before ‘<’ token
void sequence<Item>::move_back()
^
sequence.cpp:77:17: error: expected initializer before ‘<’ token
void sequence<Item>::add(const Item& entry)
^
sequence.cpp:102:17: error: expected initializer before ‘<’ token
void sequence<Item>::remove_current()
^
sequence.cpp:114:4: error: ‘sequence’ does not name a type
sequence<Item>::size_type sequence<Item>::size() const { return used; }
^
sequence.cpp:117:17: error: expected initializer before ‘<’ token
bool sequence<Item>::is_item() const { return (current_index < used); }
^
sequence.cpp:120:4: error: ‘sequence’ does not name a type
sequence<Item>::Item sequence<Item>::current() const
Here is Makefile, Also edited my changes in the file extensions.
a4s1: sequence.o sequenceTest.o
g++ sequence.o sequenceTest.o -o a4s1
sequence.o: sequence.hpp sequence.h
g++ -Wall -ansi -pedantic -c sequence.hpp
sequenceTest.o: sequenceTest.cpp sequence.hpp sequence.h
g++ -Wall -ansi -pedantic -c sequenceTest.cpp
test:
./a4s1 auto < a4test.in > a4test.out
clean:
#rm -rf sequence.o sequenceTest.o
cleanall:
#rm -rf sequence.o sequenceTest.o a4s1
"include the implementation in the header file" doesn't mean #include <sequence.cpp>, it means to actually have everything in sequence.h.
The possible solutions are:
Move everything from sequence.cpp to sequence.h and delete sequence.cpp.
Rename sequence.cpp to sequence.imp or some other extension and never compile it by itself (remove it from the makefile altogether). It will be compiled in the .cpp file(s) that #include sequence.h (this is probably what is asked of you).
Keep sequence.cpp but #include <sequence.h> at the top and use explicit template instantiation.
Templates have to be defined in every compilation unit they're used in, see here. This usually means, that their implementation has to be put inside a header file. If you want to put the implementation in a separat file anyway, you can create an "implementation file" and include it at the end of your header. That seems to be the strategy your professor is recommending.
However, the implementation file may not be treated as separate compilation unit by your built system. It should end in .imp or .hpp or something else but not .cpp.
I have built a mbed project with online ARMCC compiler, which has no complaints at all. After exporting projects to offline Keil MDK5. I got following complaints. Please advice if anyone knows how to remove/correct such issue.
SerialInterfaceProtocol/SerialInterfaceProtocol.h(16): error: #266: "CircularBuffer" is ambiguous
typedef CircularBuffer<uint8_t> SerialBuffer_t;
AlohaTransceiver/AlohaTransceiver.h(178): error: #266: "CircularBuffer" is ambiguous
CircularBuffer<AlohaFrame *> AlohaTxQueue;
AlohaTransceiver/AlohaTransceiver.cpp(44): error: #266: "CircularBuffer" is ambiguous
CircularBuffer<AlohaFrame *> AlohaRxQueue(10);
main.cpp(12): error: #266: "CircularBuffer" is ambiguous
CircularBuffer<uint8_t> SerialInputBuffer(128);
main.cpp(13): error: #266: "CircularBuffer" is ambiguous
CircularBuffer<uint8_t> SerialOutputBuffer(128);
I know CircularBuffer seems ambiguous if it has differenet types, but CircularBuffer is defined as a template, which should be used for different types? And online compiler passed, but MDK5 didn't, is there any compiler options should be enabled ?
The CircularBuffer is defined in RingBuffer.h
#ifndef RINGBUFFER_H_
#define RINGBUFFER_H_
#define DEFAULT_MAX_BUFFER_SZ 64
#include <stdint.h>
#include <stdlib.h>
template <typename T>
class CircularBuffer
{
private:
const size_t buffer_size;
size_t read_ptr;
size_t write_ptr;
size_t count;
// mutex lock
bool mux;
// overflow
bool is_over_flow;
// container
T *data;
public:
CircularBuffer(const size_t size=DEFAULT_MAX_BUFFER_SZ);
~CircularBuffer();
// psudo mutex
bool isLocked();
void lock();
void unlock();
// enqueue and dequeue
void enqueue(T in);
T dequeue();
// pointer operation
size_t getReadPtr();
size_t getWritePtr();
size_t getCounter();
// overflow
bool getOverFlow();
void clearOverFlow();
// operation
T first();
T last();
// random access
T operator[](size_t idx);
};
#endif
There are two CircularBuffer in the project, one is in mbed OS, the other is in user code. Merge them, or rename one of them.