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*****/
Related
I have an Array class that is inheriting from BaseArray class. In BaseArray, I have the protected member variables data_ and cur_size_. The Array class introduces a resize function. The problem I am encountering is that none of the protected member variables from BaseArray are seeming to be accessed in the resize function.
EDIT: Solved the max_size_ problem, but the cur_size_ and data_ file persists
Inheritance? Scope? Help?
The Error:
In file included from Array.h:41:0,
from driver.cpp:6:
Array.cpp: In member function ‘void Array<T>::resize(size_t)’:
Array.cpp:29:5: error: ‘data_’ was not declared in this scope
data_=data_;
^
Array.cpp:30:18: error: ‘cur_size_’ was not declared in this scope
if (new_size>cur_size_)
^
Array.cpp:37:5: error: ‘cur_size_’ was not declared in this scope
cur_size_=new_size;
^
The Code:
BaseArray.h:
#ifndef _BASEARRAY_H_
#define _BASEARRAY_H_
#include <cstring>
template <typename T>
class BaseArray
{
public:
/// Type definition of the element type.
typedef T type;
//constructors, destructor and methods…
protected:
/// Pointer to the actual data. m
char * data_;
/// Current size of the BaseArray.
size_t cur_size_;
};
#include "BaseArray.inl"
#include "BaseArray.cpp"
#endif // !defined _BASEARRAY_H_
Array.h:
#ifndef _ARRAY_H_
#define _ARRAY_H_
#include <cstring>
#include "BaseArray.h"
template <typename T>
class Array: public BaseArray<T> //inheriting from BaseArray
{
public:
/// Type definition of the element type.
typedef T type;
/// Default constructor.
Array (void);
Array (const Array & arr);
/// Destructor.
~Array (void);
const Array & operator = (const Array & rhs);
void resize (size_t new_size);
private:
size_t max_size_; //introduces max_size
};
#include "Array.inl"
#include "Array.cpp"
#endif // !defined _ARRAY_H_
Array.cpp:
#include "BaseArray.h"
#include "Array.h"
#include <stdexcept>
#include <iostream>
template <typename T>
Array <T>::Array (void): BaseArray<T>()
{
std::cout<<"Array def const called"<<std::endl;
}
template <typename T>
Array <T>::Array (const Array & array): BaseArray<T>(array)
{
}
template <typename T>
Array <T>::~Array (void)
{
}
template <typename T>
void Array <T>::resize (size_t new_size)
{
this->data_= this->data_;
if (new_size>this->cur_size_)
{
max_size_ = new_size-this->cur_size_-1;
this->cur_size_=new_size;
for (max_size_; max_size_<=new_size; max_size_++)
this->data_[max_size_]=0;
}
this->cur_size_=new_size;
}
/* Also tried it like this:
template <typename T>
void Array <T>::resize (size_t new_size)
{
BaseArray<T>::data_= BaseArray<T>::data_;
if (new_size>BaseArray<T>::cur_size_)
{
max_size_ = new_size-BaseArray<T>::cur_size_-1;
BaseArray<T>::cur_size_=new_size;
for (max_size_; max_size_<=new_size; max_size_++)
BaseArray<T>::data_[max_size_]=0;
}
BaseArray<T>::cur_size_=new_size;
} */
regarding the first error, you have no max_size() member declared in Array.
regarding the second error, name lookup in templates follows a two stage logic, where non dependent expressions are looked up at definition point, whereas dependent expressions are looked up at instantiation point;
This means that when the compiler sees data_ it thinks it's a variable located somewhere else; at best, it won't find it giving you an error, at worst, it will give you the wrong variable !
In order to solve the problem, you need to make that a dependent expression, the most obvious way being replacing all data_ with this->data_, etc...
regarding your code organization, define your templates into a single header file; if you really want to split member implementations place them in a single file with a sensible file extension ( inl is ok, cpp is not )...
Every time I create a new project in my workplace I run into the problem with templates. For example, I'll create a new class, which CodeLite will create a .h file and a .cpp file for me, and then I'll change that .cpp file into a .template by renaming the file. It sometimes works, and sometimes doesn't. Sometimes I have to clean my workplace for it to work, other times I need to exit out of CodeLite and reopen it. This time these solutions are not working for me, but maybe I am missing something. Here's my code:
.h file
#ifndef TABLE1_H
#define TABLE1_H
#include <cstdlib> // Provides size_t
namespace main_savitch_12A
{
template <class RecordType>
class table
{
public:
// MEMBER CONSTANT -- See Appendix E if this fails to compile.
static const std::size_t CAPACITY = 811;
// CONSTRUCTOR
table( );
// MODIFICATION MEMBER FUNCTIONS
void insert(const RecordType& entry);
void remove(int key);
// CONSTANT MEMBER FUNCTIONS
bool is_present(int key) const;
void find(int key, bool& found, RecordType& result) const;
std::size_t size( ) const { return used; }
private:
// MEMBER CONSTANTS -- These are used in the key field of special records.
static const int NEVER_USED = -1;
static const int PREVIOUSLY_USED = -2;
// MEMBER VARIABLES
RecordType data[CAPACITY];
std::size_t used;
// HELPER FUNCTIONS
std::size_t hash(int key) const;
std::size_t next_index(std::size_t index) const;
void find_index(int key, bool& found, std::size_t& index) const;
bool never_used(std::size_t index) const;
bool is_vacant(std::size_t index) const;
};
}
#include "table1.template" // Include the implementation.
#endif
.template file
template<class RecordType>
table<RecordType>::table(){
used = 32;
}
main file
#include <stdio.h>
#include "table1.h"
int main(int argc, char **argv)
{
printf("hello world\n");
return 0;
}
My template and my .h files are called table1. The error I am getting when I run the program is in the template file. It reads: "table does not name a type" How can I fix this issue?
In your template implementation your are missing the namespace, use this:
template <class RecordType>
main_savitch_12A::table<RecordType>::table()
{
used = 32;
};
I know that when declaring an array I have to specified its size with a constant value, but in this case I'm creating a const value that is also a const expression, initialized with a literal value, which can be evaluated in compiling time, but I keep having the error on those two cases:
CASE I:
Stack.h
#ifndef STACK_H
#define STACK_H
extern const unsigned MAX;
class Stack {
public:
/* Declarations here ... */
private:
unsigned n;
int stack[MAX];
};
#endif // STACK_H
Stack.cpp
#include <iostream>
#include "Stack.h"
extern const unsigned MAX = 5;
Stack::Stack() {
this->n = 0;
}
int Stack::pop() {
int pop = -1;
if (n > 0) {
pop = this->stack[n - 1];
this->stack[n - 1] = 0;
--n;
} else {
std::cout << "StackUnderFlowException:: Stack Data Structure is Empty!" << std::endl;;
}
return pop;
}
int Stack::getStackTop() {
return this->n > 0 ? this->stack[n - 1] : -1;
}
void Stack::push(int v) {
if (n < MAX) {
this->stack[n] = v;
++n;
} else {
std::cout << "StackOverFlowException:: Stack Data Structure is Full!" << std::endl;
}
}
Error:
In file included from p38.cpp:2:
./Stack.h:18:6: error: fields must have a constant size: 'variable length array in structure' extension will never be supported
int stack[MAX];
^
1 error generated.
In file included from Stack.cpp:2:
./Stack.h:18:6: error: fields must have a constant size: 'variable length array in structure' extension will never be supported
int stack[MAX];
^
And things get even more weird in the second case ...
CASE II:
Stack.h
#ifndef STACK_H
#define STACK_H
extern const unsigned MAX = 5;
class Stack {
public:
Stack();
int pop();
int getStackTop();
void push(int v);
bool isEmpty();
void printStack(void) const;
private:
unsigned n;
int stack[MAX];
};
#endif // STACK_H
Stack.cpp
#include <iostream>
#include "Stack.h"
using namespace std;
Stack::Stack() {
this->n = 0;
}
/* More code here ... */
Error:
duplicate symbol _MAX in:
/var/folders/r3/zbrrqh7n5tg0vcnpr9_7j0nr0000gn/T/p38-ac46b9.o
/var/folders/r3/zbrrqh7n5tg0vcnpr9_7j0nr0000gn/T/Stack-a5d98e.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I've fixed CASE II just by removing the extern keyword, and case I was fixed using the #define MAX 5 in header instead of using some constant variable, the thing is even tough I've fixed the problem I want to have a better understanding of C++, a I would like to know the cause of those errors since I didn't get it quite well. Can someone give me an explanation ? Thanks in advance!
There is a difference between compile time constant and run time constant.
extern const unsigned MAX;
declares a run time constant, not a compile time constant. It can be initialized to 5, 10, 20, or anything else at run time. Once initialized, its value remain constant.
Since it is not a compile time constant, it cannot be used as the size of an array.
To use it as compile time constant, use:
const unsigned MAX = 5;
in the .h file.
extern const unsigned MAX = 5;
does not work since that not only declares the variable but defines it too. Any .c file that #includes the .h file ends up defining the variable, which explain the duplicate symbol linker error.
int stack[MAX];
your error lies here u have to compulsorily specify the size.
e.g int stack[20];
I have created a class that abstracts a SPI flash chip library called SerialFlash by creating an abstract class of Print.h. When I try to print to this by using the ArduinoJson library, I get an error:
src/FlashMemory.cpp:99:36: error: no matching function for call to 'ArduinoJson::JsonObject::printTo(<unresolved overloaded function type>)'
root.printTo(serialFlashPrint);
^
lib/ArduinoJson/include/ArduinoJson/Internals/../Internals/JsonPrintable.hpp:34:10: note: size_t ArduinoJson::Internals::JsonPrintable<T>::printTo(Print&) const [with T = Ardu
inoJson::JsonObject; size_t = unsigned int]
size_t printTo(Print &print) const {
^
lib/ArduinoJson/include/ArduinoJson/Internals/../Internals/JsonPrintable.hpp:34:10: note: no known conversion for argument 1 from '<unresolved overloaded function type>' to
'Print&'
The file referenced in the error above is here: https://github.com/bblanchon/ArduinoJson/blob/master/include/ArduinoJson/Internals/JsonPrintable.hpp
This is the header file for the class:
#include <Arduino.h>
#include <SerialFlash.h>
#include "Print.h"
#ifndef _SerialFlashPrint_h_
#define _SerialFlashPrint_h_
class SerialFlashPrint : public Print {
public:
SerialFlashPrint(SerialFlashFile *file);
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buffer, size_t size);
private:
char buf[1];
uint16_t _current_byte;
SerialFlashFile * _file;
};
#endif
And the cpp file:
#include "serialFlashPrint.h"
SerialFlashPrint::SerialFlashPrint(SerialFlashFile * file) : Print() {
this->_file = file;
this->_current_byte = 0;
}
size_t SerialFlashPrint::write(uint8_t c) {
if(_current_byte == 0){
_file->erase();
_file->seek(0);
}
sprintf(buf, "%c", c);
_file->write(buf, 1);
_current_byte++;
return 0;
}
size_t SerialFlashPrint::write(const uint8_t *buffer, size_t size){
_file->erase();
_file->seek(0);
_file->write(buffer, size);
_file->write(NULL, 1);
return 0;
};
Generally, you use print function as: the root.printTo(Serial). This code is based upon an abstraction (which I got to work previously) called Chunked output that can be seen here: https://github.com/bblanchon/ArduinoJson/wiki/Bag-of-Tricks
Does anyone have any clues for me to figure out why I am getting <unresolved overloaded function type> instead of Print&?
<unresolved overloaded function type> means that the compiler found a function with several overloads and doesn't know which one to use.
You most likely have several serialFlashPrint() in your code or libraries.
If not, then you may have triggered the Most vexing parse:
SerialFlashPrint serialFlashPrint; // <- creates an instance of SerialFlashPrint
SerialFlashPrint serialFlashPrint(); // <- declares a function returning a SerialFlashPrint
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.