I'm trying to write a container class using C++ and templates. However, I'm having a compilation error I don't understand...
The variable elems is a private vector, declaration is:
private:
vector<DataType> elems;
The vector is a custom vector. Its constructor is:
vector::vector(int init_capacity) : vect_capacity(init_capacity), vect_size(0), vect_elems(NULL){
assert(init_capacity >= 0);
if (init_capacity > 0){
vect_elems = new Object[init_capacity];
}
}
The constructor can be seen below:
template <class DataType>
bag<DataType>::bag(int init_capacity) : elems(init_capacity) {
}
This code returns the following error:
../src/vector.h: In instantiation of ‘vector<DataType>::vector(int) [with DataType = int]’:
../src/bag.h:33:60: required from ‘bag<DataType>::bag(int) [with DataType = int]’
../src/bag_test.cpp:6:17: required from here
I honestly have no idea what could be possibly happening. Will be immensely grateful to anyone that can point me in the right direction...
Sorry for the very stupid question. It's true that the compiler does complain about this, but the code actually compiles. Thanks to #WhozCraig and #n.m who insisted that this wasn't an error, I noticed that it actually was building. Thanks! For future reference, I do post the whole message:
**** Build of configuration Debug for project ADS ****
make all
Building file: ../src/bag_test.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/bag_test.d" -MT"src/bag_test.d" -o "src/bag_test.o" "../src/bag_test.cpp"
In file included from ../src/bag_test.cpp:2:0:
../src/bag.h:23:66: warning: friend declaration ‘std::ostream& operator<<(std::ostream&, const bag<DataType>&)’ declares a non-template function [-Wnon-template-friend]
../src/bag.h:23:66: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
In file included from ../src/bag.h:2:0,
from ../src/bag_test.cpp:2:
../src/vector.h: In instantiation of ‘vector<DataType>::vector(int) [with DataType = int]’:
../src/bag.h:34:53: required from ‘bag<DataType>::bag(int) [with DataType = int]’
../src/bag_test.cpp:6:17: required from here
../src/vector.h:100:6: warning: ‘vector<int>::vect_capacity’ will be initialized after [-Wreorder]
../src/vector.h:99:6: warning: ‘int vector<int>::vect_size’ [-Wreorder]
../src/vector.h:108:1: warning: when initialized here [-Wreorder]
Finished building: ../src/bag_test.cpp
Building target: ADS
Invoking: GCC C++ Linker
g++ -o "ADS" ./src/bag_test.o
Finished building target: ADS
**** Build Finished ****
Related
My class is size parameterized. In one of its methods I have to create a temporary array, but I don't know how to pass the class's size template to the member function. This is how I tried:
#include <array>
template<unsigned int N>
class MyClass{
std::array<int,N> m_data;
public:
void myFunc(){
std::array<int,N> tempArray;
}
};
int main(){
MyClass<5> obj;
obj.myFunc();
}
Edit:
Build log:
C:\Windows\system32\cmd.exe /C ""C:/Program Files/mingw-w64/x86_64-6.3.0-win32-seh-rt_v5-rev1/mingw64/bin/mingw32-make.exe" -j6 SHELL=cmd.exe -e -f Makefile"
"----------Building project:[ hatizsak_konyv - Debug ]----------"
mingw32-make.exe[1]: Entering directory 'E:/progi/c++/CodeLite/Other/algoritmusok/dinamikus_programozas/hatizsak_konyv'
"C:/Program Files/mingw-w64/x86_64-6.3.0-win32-seh-rt_v5-rev1/mingw64/bin/g++.exe" -c "E:/progi/c++/CodeLite/Other/algoritmusok/dinamikus_programozas/hatizsak_konyv/main.cpp" -g -O0 -Wall -o ./Debug/main.cpp.o -I. -I.
E:/progi/c++/CodeLite/Other/algoritmusok/dinamikus_programozas/hatizsak_konyv/main.cpp: In instantiation of 'void MyClass<N>::myFunc() [with unsigned int N = 5u]':
E:/progi/c++/CodeLite/Other/algoritmusok/dinamikus_programozas/hatizsak_konyv/main.cpp:15:16: required from here
E:/progi/c++/CodeLite/Other/algoritmusok/dinamikus_programozas/hatizsak_konyv/main.cpp:8:27: warning: unused variable 'tempArray' [-Wunused-variable]
std::array<int,N> tempArray;
^~~~~~~~~
"C:/Program Files/mingw-w64/x86_64-6.3.0-win32-seh-rt_v5-rev1/mingw64/bin/g++.exe" -o ./Debug/hatizsak_konyv #"hatizsak_konyv.txt" -L.
mingw32-make.exe[1]: Leaving directory 'E:/progi/c++/CodeLite/Other/algoritmusok/dinamikus_programozas/hatizsak_konyv'
====1 errors, 1 warnings====
Template parameters are visible inside methods of the template class; the code is correct.
There's no error at all, nor in the provided code example, nor in the build log. The message in the build log is just a warning (with the lines before providing context for it), which correctly warns you about the fact that that variable isn't used, as per the -Wall option provided on the command line. Other than that, the code compiles fine, both on ideone and on my machine (where it gives you exact same warning, not error).
[matteo#teolapkubuntu /tmp]$ g++ -Wall -Wextra -std=c++11 stuff.cpp
stuff.cpp: In instantiation of ‘void MyClass<N>::myFunc() [with unsigned int N = 5u]’:
stuff.cpp:15:16: required from here
stuff.cpp:8:27: warning: unused variable ‘tempArray’ [-Wunused-variable]
std::array<int,N> tempArray;
^~~~~~~~~
The "1 error" message at the end of the build log is just CodeLite misinterpreting the compiler output; there is an open bug about it, with conditions similar to yours.
I am using boost::thread to call an in-class member function from within a different member function of the same class. The declaration of the method I would like to thread is:
void ClassName::nnMetropolisStep(double random, std::vector<int> nums);
And I am creating threads from another member function via:
boost::thread* tThread = new boost::thread(&ClassName::nnMetropolisStep,
this,
someRandom,someNums);
These are the only calls to boost functions in the code I'm using.
I've seen in other questions that this syntax will work for non-static member functions (and there are no access issues with the way I have constructed the threads). However, when I compile, I get the following error:
g++ -fPIC -std=c++11 -c -g -Wall `root-config --cflags --glibs` -MMD -c -o obj/IsingModel.o src/IsingModel.cpp
In file included from /usr/include/boost/thread/pthread/mutex.hpp:11:0,
from /usr/include/boost/thread/mutex.hpp:16,
from /usr/include/boost/thread/pthread/thread_data.hpp:12,
from /usr/include/boost/thread/thread.hpp:17,
from /usr/include/boost/thread.hpp:13,
from src/interface/IsingModel.h:11,
from src/IsingModel.cpp:11:
/usr/include/boost/thread/locks.hpp: In instantiation of 'boost::unique_lock<Mutex>& boost::unique_lock<Mutex>::operator=(boost::unique_lock<Mutex>&&) [with Mutex = boost::mutex]':
/usr/include/boost/thread/future.hpp:414:33: required from here
/usr/include/boost/thread/locks.hpp:269:22: error: cannot bind 'boost::unique_lock<boost::mutex>' lvalue to 'boost::unique_lock<boost::mutex>&&'
swap(temp);
^
/usr/include/boost/thread/locks.hpp:279:14: note: initializing argument 1 of 'void boost::unique_lock<Mutex>::swap(boost::unique_lock<Mutex>&&) [with Mutex = boost::mutex]'
void swap(unique_lock&& other)
^
make: *** [obj/IsingModel.o] Error 1
What is going on? Clearly I am either doing something incorrectly, or worse, there's an issue with my compiler setup.
I figured out the answer by removing all references to boost except for the #include statement. In my header file, I was using
#include "boost/thread.hpp"
Which worked, but was not correct. Once I changed it to
#include "boost/thread/thread.hpp"
Everything compiled without complaint.
I'm using version 1.41.0 of boost.
You need to use boost::bind function during thread object creation. For example:
double rand = 0;
std::vector<int> myVector;
ClassName obj;
auto threadObj = new boost::thread(boost::bind(&ClassName::nnMetropolisStep,&obj,rand,myVector));
I am currently working on a Oculus Rift project (DK1) on Ubuntu 14.04 and I try to compile a github projet.
This is a Qt project written in C++. I have the following error about "unique_ptr". I think have installed the right libraries. I know this code have already worked on a Ubuntu computer.
g++ -c -m64 -pipe -Ofast -Wno-deprecated -O2 -std=c++0x -Wall -W -fPIE -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64 -I. -o Camera.o Camera.cpp
In file included from Include/OVR/LibOVR/Include/../Src/OVR_Device.h:33:0,
from Include/OVR/LibOVR/Include/OVR.h:35,
from Oculus.h:13,
from Input.h:13,
from Camera.h:12,
from Camera.cpp:1:
Include/OVR/LibOVR/Include/../Src/OVR_DeviceMessages.h: In constructor ‘OVR::MessageCameraFrame::MessageCameraFrame(OVR::DeviceBase*)’:
Include/OVR/LibOVR/Include/../Src/OVR_DeviceMessages.h:255:13: warning: ‘OVR::MessageCameraFrame::CameraHandle’ will be initialized after [-Wreorder]
UInt32* CameraHandle; // Identifies the camera object associated with this frame
^
Include/OVR/LibOVR/Include/../Src/OVR_DeviceMessages.h:249:18: warning: ‘const UByte* OVR::MessageCameraFrame::pFrameData’ [-Wreorder]
const UByte* pFrameData; // a ptr to frame data.
^
Include/OVR/LibOVR/Include/../Src/OVR_DeviceMessages.h:226:5: warning: when initialized here [-Wreorder]
MessageCameraFrame(DeviceBase* dev)
^
Camera.cpp: In constructor ‘Camera::Camera(const vec3&, const vec3&, const vec3&, float, float, const Input&)’:
Camera.cpp:20:18: error: use of deleted function ‘Input::Input(const Input&)’
speed_ {speed}
^
In file included from Camera.h:12:0,
from Camera.cpp:1:
Input.h:33:7: note: ‘Input::Input(const Input&)’ is implicitly deleted because the default definition would be ill-formed:
class Input
^
Input.h:33:7: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = GenericOculus; _Dp = std::default_delete<GenericOculus>]’
In file included from /usr/include/c++/4.8/memory:81:0,
from LogCpp/Log.h:8,
from Oculus.h:23,
from Input.h:13,
from Camera.h:12,
from Camera.cpp:1:
/usr/include/c++/4.8/bits/unique_ptr.h:273:7: error: declared here
unique_ptr(const unique_ptr&) = delete;
^
Camera.cpp:20:18: warning: a temporary bound to ‘Camera::input_’ only persists until the constructor exits [-Wextra]
speed_ {speed}
^
make: *** [Camera.o] Erreur 1
Thank you
The problem here lies in this message:
Input.h:33:7: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&)
You're apparently trying to construct a unique_ptr from another unique_ptr. That's forbidden, as unique_ptr can't be copied (that's the point of having a unique pointer). You can only move a unique_ptr to transfer ownership.
So you'll have to revise that code with this information in mind.
Note: As you apparently have a member unique_ptr in your class, and as its copy constructor is deleted (i.e. explicitely forbidden), thus the default copy constructor of your class is itself deleted, which explains the following error message in your stack:
Camera.cpp:20:18: error: use of deleted function ‘Input::Input(const Input&)
The following example
// file mysort.cc
#include <string>
#include <vector>
#include <algorithm>
#include <string.h>
void mysort (const char**tab, unsigned size) {
std::vector<int> vecix;
vecix.resize(size);
struct CompareIndex {
const char**t;
CompareIndex(const char**p) : t(p) {};
bool operator() (int l, int r) {
return strcmp(t[l], t[r])<0;
}
};
CompareIndex compix(tab);
for (unsigned ix=0; ix<size; ix++) vecix[ix] = ix;
std::stable_sort(vecix.begin(), vecix.end(), compix);
std::vector<const char*> vecstr;
vecstr.resize(size);
for (unsigned ix=0; ix<size; ix++) vecstr[ix] = tab[vecix[ix]];
for (unsigned ix=0; ix<size; ix++) tab[ix] = vecstr[ix];
}
fails to compile (using GCC 4.8.2 on Debian/Sid/x86-64 in C++03 standard)
mysort.cc: In function 'void mysort(const char**, unsigned int)':
mysort.cc:19:58: error: no matching function for call to
'stable_sort(std::vector<int>::iterator,
std::vector<int>::iterator,
mysort(const char**, unsigned int)::CompareIndex&)'
std::stable_sort(vecix.begin(), vecix.end(), compix);
^
In file included from /usr/include/c++/4.8/algorithm:62:0,
from mysort.cc:4:
/usr/include/c++/4.8/bits/stl_algo.h:5682:5: note:
template<class _RAIter, class _Compare>
void std::stable_sort(_RAIter, _RAIter, _Compare)
stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
^
/usr/include/c++/4.8/bits/stl_algo.h:5682:5: note:
template argument deduction/substitution failed:
mysort.cc: In substitution of 'template<class _RAIter, class _Compare>
void std::stable_sort(_RAIter, _RAIter, _Compare)
[with _RAIter = __gnu_cxx::__normal_iterator<int*, std::vector<int> >;
_Compare = mysort(const char**, unsigned int)::CompareIndex]':
mysort.cc:19:58: required from here
mysort.cc:19:58: error: template argument for
'template<class _RAIter, class _Compare>
void std::stable_sort(_RAIter, _RAIter, _Compare)'
uses local type 'mysort(const char**, unsigned int)::CompareIndex'
std::stable_sort(vecix.begin(), vecix.end(), compix);
^
mysort.cc:19:58: error: trying to instantiate
'template<class _RAIter, class _Compare>
void std::stable_sort(_RAIter, _RAIter, _Compare)'
The above was compiled with GCC 4.8 using
g++ -Wall -c mysort.cc
I am getting the same error with
g++ -std=c++03 -Wall -c mysort.cc
or with
g++ -std=c++98 -Wall -c mysort.cc
but no errors with
g++ -std=c++11 -c mysort.cc
given that my g++ -v is a gcc version 4.8.2 (Debian 4.8.2-12)
but with Clang/LLVM 3.4 compiling with
clang++ -Wall -c mysort.cc
I'm getting only a warning:
mysort.cc:19:7: warning: template argument uses local
type 'CompareIndex'
[-Wlocal-type-template-args]
std::stable_sort(vecix.begin(), vecix.end(), compix);
^~~
1 warning generated.
(and I still get only a warning not an error when passing -std=c++03 or -std=c++98 to clang++ but no warnings with clang++ -std=c++11)
so my question is: why the error by GCC and the warning by Clang? Is my code legal and without undefined behavior (w.r.t. the C++03 standard)? Should I make my CompareIndex a global struct in my compilation unit?
motivations
Of course, this is a silly way to sort an array of C strings.
The real code is a bit different. In fact, I am trying to use std::stable_sort in my MELT plugin (a domain specific language to extend and customize GCC). MELT is generating C++ code and has a copying garbage collector (so pointers are moved by the GC). Hence, I need to sort using an array of indexes: the compare function in fact calls a MELT closure (which could trigger the copying GC at arbitrary moment), so I need to sort by indexes (and not by raw pointers). I want to keep the C++ code generated by MELT conforming to the C++ standard (03 or 98) required to compile GCC.
work-around
Thanks to juanchopanza's answer I've solved the issue by moving the declaration of CompareIndex at global scope before mysort.
I just committed the svn revision 206748 of the MELT branch of GCC; its file gcc/melt/warmelt-base.melt contains now a multiple_sort_new MELT function (to replace multiple_sort when it is working well) using std::stable_sort, and a global Melt_Sort_Compare_Index class in the generated C++ code.
Using local types as template arguments is not allowed in C++03.
From ISO/IEC 14882, 14.3.1 Template type arguments [temp.arg.type]:
A local type, a type with no linkage, an unnamed type or a type
compounded from any of these types shall not be used as a
template-argument for a template type-parameter.
The example given is along these lines:
template <typename T> struct Foo {};
void foo()
{
struct Bar {};
Foo<Bar> b1; // error: local type used as template-argument
Foo<Bar*> x4; // error: pointer to local type used as template-argument
}
This restriction has been lifted in C++11.
I am unable to Compile GMP on OSX 10.9. I am not entirely sure, if the problem is OSX 10.9 specific but what happens is compilation is successful but make check fails.
Please note if I don't use --enable-cxx compilation and make check both succeeds.
The full error is:
c++ -DHAVE_CONFIG_H -I. -I../.. -I../.. -I../../tests -O2 -pedantic -fomit-frame-pointer -m64 -mtune=corei7 -march=corei7 -c -o t-cast.o t-cast.cc
brew: superenv removed: -O2 -pedantic -m64 -mtune=corei7 -march=corei7
In file included from t-cast.cc:20:
In file included from ../../gmp.h:51:
/Applications/Xcode5-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/cstddef:51:9: error: no member named
'ptrdiff_t' in the global namespace
using ::ptrdiff_t;
~~^
In file included from t-cast.cc:21:
In file included from ../../gmpxx.h:29:
In file included from /Applications/Xcode5-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/algorithm:594:
In file included from /Applications/Xcode5-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:596:
/Applications/Xcode5-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/iterator:386:13: error: unknown type name
'ptrdiff_t'
typedef ptrdiff_t difference_type;
^
/Applications/Xcode5-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/iterator:413:56: error: unknown type name
'ptrdiff_t'
template<class _Category, class _Tp, class _Distance = ptrdiff_t, ^/Applications/Xcode5-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/iterator:720:66: error: unknown type name
'ptrdiff_t' class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
^
/Applications/Xcode5-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/iterator:720:54: error: template parameter
missing a default argument
class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
^
/Applications/Xcode5-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/iterator:720:27: note: previous default
template argument defined here class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
Remove the __need_size_t define and undef in gmp.h. It'll import ptrdiff_t too, rather than just size_t.