Nick Evan commented: good info! +6
Salem commented: Much better :) +17
John A commented: Thanks for the clarification. +15
predicate versions of std::mismatch
std::search
std::lexicographical_compare
std::equal
etc.
if it is to be part of a reusable library, as general as possible (perhaps with some syntactic sugar).
if not, just sufficient to meet the (future) requirements of the program i'm writing.
you are trying to multiply a Matrix<double>
and a Point<float>
the overloaded binary * operator needs to be:
template<class T> class Matrix
{
// ...
template< typename U >
Point<U> operator* (const Point<U>& p) const { return Point<U>(0,0,0); }
};
also,
template<class T, class C>
void foo(T x, T y, T z)
{
Point<T> o1(0,0,0);
// to the compiler this is the declaration of a function
// with the signature Matrix<C> (*)(C,C,C)
// Matrix<C> m(C(x),C(y), C(z));
// modify to something like
Matrix<C> m( C(x), C(y), ( C(z) ) );
// note the extra () - ( C(z) ) is an expression
// and not the declaration of a formal parameter
m * o1;
}
> What compiler are you using?
the non-conforming code compiles on gcc 4.1 (which is known to be non-conforming with respect to template template parameters).
gcc 4.2 and gcc 4.3 correctly gives errors.
there are several discussions on the web regarding this; here is a succinct one:
http://objectmix.com/c/388843-port-gcc-4-3-template-template-issue.html
> If you're never going to use a custom allocator, it doesn't make any sense to do that extra work.
the fundamental problem with your code is not that it does not cater for a custom allocator for the container. it is that it does not compile.
> typename is not followed by a name, which I find confusing
since the intent is to declare a template template type (ttp), the identifier following typename is just a place-holder (like the name of a formal parameter to a function) and can be omitted.
http://www.comeaucomputing.com/techtalk/templates/#ttp
a standard container has *two* template parameters; the value_type and the allocator_type.
the function should be:
template< typename T, typename A, template
<typename VALUE_TYPE,typename ALLOCATOR_TYPE> class Container >
int my_func( std::map<T, Container<T,A> >& arg )
{
typedef std::map< T, Container<T,A> > Map;
typedef typename Map::iterator Iter;
typedef typename Container<T,A>::iterator CIter;
int count = 0;
// ...
return count;
}
for a standard container, begin() and end() are overloaded on the const specifier.
on a modifiable container, begin() and end() return container::iterator.
on a const container, begin() and end() returns container::const_iterator.
template< typename CNTR > // CNTR is a standard container
void foo( CNTR& cntr, const CNTR& const_cntr )
{
typename CNTR::iterator iter = cntr.begin() ;
typename CNTR::const_iterator const_iter = const_cntr.begin() ;
typename CNTR::reverse_iterator rev_iter = cntr.rbegin() ;
typename CNTR::const_reverse_iterator const_rev_iter = const_cntr.rbegin() ;
}
this code will not compile:
#include <vector>
void f( std::vector<int>::const_iterator& i )
{ std::cout << *i << std::endl; }
int main()
{
std::vector<int> v;
std::vector<int>::iterator b = v.begin() ;
f(b);
}
but this will:
template< typename ITERATOR > void f( ITERATOR i )
{ std::cout << *i << std::endl; }
#include <vector>
int main()
{
std::vector<int> v;
std::vector<int>::iterator b = v.begin() ;
f(b);
}
c++09: containers also have:
// ...
const_iterator cbegin() const;
const_iterator cend () const;
const_reverse_iterator crbegin() const;
const_reverse_iterator crend () const;
// ...
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1674.pdf
so things become a bit more convenient.
note: prefer passing an iterator by value (rather than by modifiable reference);
it is more flexible for iterations to be non-intrusive.
concept: the value_type of a standard container (the type of the object stored in the container) is required to be Assignable http://www.sgi.com/tech/stl/Assignable.html
a const T
( or for that matter a T&
) is not Assignable and cannot be the value_type in a standard container.
> I'm not sure how a bus error could occur when calling an empty function.
the bus error occurs before the call to void Pawn::move(int rank, int file) { }
Piece::move
is virtual, a vtbl lookup is required. the vtbl pointer is invalid for the object.
how are you initializing Board::pieces
?
perhaps, you could post the code for Board::Board();
> ...but I want to be able to modify the Piece...
> Does this mean that I should forget about const qualifiers for this task
yes, return a Piece*
( instead of a const Piece*
).
since you are returning a pointer by value, the const in Piece* const
is superfluous.
> I return a Piece* const
which should allow me to modify the Piece object.
> However, when I try to do so I get a Bus error:
> p->move(0,0); // Bus error
> Why is this?
the most likely reason is that in Piece::move
, you are attempting to access an invalid address.
a less likely reason is that (depends on the CPU ) you are trying to access an unaligned address.
http://en.wikipedia.org/wiki/Bus_error
> What is the difference between Piece* const*
and Piece** const
? Piece* const*
=> (modifiable) pointer to a constant pointer to a (modifiable) Piece Piece** const
=> constant pointer to a (modifiable) pointer to a (modifiable) Piece
what follows the const specifier is a const.
to enforce const-correctness (a good idea), use const
as required. eg.
#include <cstddef>
struct Piece ;
struct board
{
enum { N = 8 } ;
struct the_row
{
const Piece* operator[] ( std::size_t j ) const
{ return j<board::N && row!=0 ? row[j] : 0 ; }
private :
const Piece* const* row ;
explicit the_row( const Piece* const* r ) : row(r) {}
friend class board ;
} ;
the_row operator[] ( std::size_t i ) const
{ return the_row( i<board::N ? array[i] : 0 ) ; }
// ...
private:
Piece* array[N][N] ;
};
> since a pointer to an object of the Board class is returned, I cannot declare any of the
> methods/arguments/return values as const, which seems like bad style.
why can't you? you should return a const pointer.
then you can (and you should) declare selectors as const.
the simplest (and the most efficient) way to copy a text file (C++):
std::ifstream srce( inputfilename ) ;
std::ofstream dest( outputfilename ) ;
dest << srce.rdbuf() ;
if the escape sequence encodings are the same for both files (for instance they are on the same file system), you can squeeze a few cpu cycles by specifying std::ios::binary
.
the exercises (many of them open-ended) given in C++ Primer, 3/E http://www.pearsonhighered.com/academic/product/0,,0201824701,00%2Ben-USS_01DBC.html
perhaps, along with the C++ Primer Answer Book http://search.barnesandnoble.com/C-Primer-Answer-Book/Clovis-L-L-Tondo/e/9780201309935
> So I could write something like this:
...
no, you can't. you need to write something like:
std::size_t max = 0; // Number set by user at execution
// ...
long (*pBigArray)[100][100] = new long [max][100][100];
> Can someone tell me why I can't write the above?
for performing pointer arithmetic (including array subscrpt) correctly, the compiler needs to know (at compile time) the size of the element that is pointed to.
> Is there a way to get around this?
the simplest would be to use std::vector
asynchronous write to a file by aio_write
http://www.freebsd.org/cgi/man.cgi?query=aio_write&apropos=0&sektion=2&manpath=FreeBSD+7.0-stable&format=html is POSIX.1, and should work on linux.
> ...maybe the array is automatically cleared from memory when the application closes...
right, provided your program is running under an os ( like unix, windows, linux ... ) which gives a separate virtual address space for each process. when a process terminates, all the resources it owns are reclaimed by the system; and its private memory would be deallocated.
> method that I can use to force M$ windows to listen to my priority designations?
run under an account with elevated privileges.
on a normal system, only the memory manager worker threads (balance set manager, modified page writer and mapped page writer) run under real-time priority.
by default, only administrative accounts have the necessary privilege
( "SeIncreaseBasePriorityPrivilege"
) required to set real-time priorities.
> option to limit a thread or a program to a single core SetProcessAffinityMask
http://msdn.microsoft.com/en-us/library/ms686223(VS.85).aspx SetThreadAffinityMask
http://msdn.microsoft.com/en-us/library/ms686247(VS.85).aspx
case 1 : float hipvalley(); // this is the Hip/Valley choice.
that is merely a declaration of the function hipvalley.
to invoke the function (and ignore its result), write
case '1' : hipvalley(); // this is the Hip/Valley choice.
#include <cstdlib>
#include <string>
inline char random_digit() { return '0' + std::rand() % 10 ; }
inline std::string random_pin( std::size_t ndigits )
{
std::string pin ;
for( std::size_t i = 0 ; i < ndigits ; ++i ) pin += random_digit() ;
return pin ;
}
a nontype template parameter can be a pointer or a reference to an object with external linkage.
the object itself need not be a constant. eg.
struct A
{
explicit A( int ii=7 ) : i(ii) {}
void modifier() { ++i ; }
int i ;
};
struct rtc
{
template< A* pointer >
static inline void do_modify_via_ptr() { pointer->modifier() ; }
template< A& reference >
static inline void do_modify_via_ref() { reference.modifier() ; }
};
A a ; // object with external linkage
int main()
{
rtc::do_modify_via_ptr< &a >() ;
rtc::do_modify_via_ref< a >() ;
}
or
// ...
int Strength = 5 ;
int Intelligence = 2 ;
int Agility = 3 ;
int Defense = 3 ;
int Health = 10 ;
int Level = 1 ;
for(;;)
{
char classChoice ;
cin >> classChoice ;
if( classChoice=='W' || classChoice=='w' )
{
break ;
}
else if( classChoice=='M' || classChoice=='m' )
{
Strength = 2 ;
Intelligence = 5 ;
Defense = 2 ;
break;
}
else
{
cerr << "You did not enter a legal value.\n";
}
}
Character player( Strength, Intelligence, Agility,
Defense, Health, Level ) ;
player.DisplayStats() ;
// ...
does the term 'smart pointer' ring a bell?
http://www.informit.com/articles/article.aspx?p=31529
http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/smart_ptr.htm
http://en.wikipedia.org/wiki/Technical_Report_1#Smart_Pointers
and why not use std::vector
as a container?
> I have a function double Min(vector<geom_Point3> &Points, int n);
> Then in another class, I have a private member:
> vector<geom_Point3> Vertices_;
> and in a class function, I call: min_x = Min(Vertices_, 0);
> however, I get error: qualifiers dropped in binding reference...
> What does that mean??
> i fixed it by taking the & out of the Max() declaration...
> but then isn't it passing the entire array...
> So why can't I put the & there?
the qualifiers the compiler is mentioning are cv-qualifiers (const/volatile)
the class member function where you call min_x = Min(Vertices_, 0);
is a const
member function.
modify the function signature to make it const-correct double Min( const vector<geom_Point3>& Points, int n ) ;
and you should be ok.
> I have to sort it much, much more quicker, are 10 seconds possible?.
with 10 seconds at your disposal, you can sort it any which way you like.
the fastest way would perhaps be to use std::partition
to move the most frequently occurring values (which are also the smallest values) to the front of the sequence. sort the remaining 40% or so of the sequence using a std::sort
.
it doesn't really matter if you are sorting a file; i/o would dominate.
here are some measurements of a sample run on a sequence of 500000 integers (roughly 30% of them have value 1, 20% are 2, 10% 3, remainder are [3,1000] ):
a. std::sort on the sequence: 0.0390625 seconds
b. std::partition for 1, 2 and 3, std::sort for the rest: 0.0234375 seconds
c. same as b, but read from a file sort and write to another file: 0.335938 seconds
>dmesg | grep CPU:
CPU: Intel(R) Pentium(R) 4 CPU 2.80GHz (2800.10-MHz 686-class CPU)
perhaps, Salem's suggestion of using a command line sort program is all that you need.
> ...139 files, with 16,000 lines of code...
> ...So how do I start to disect messy code that is not documented and not written by me?
> How does somebody look at code and start to make sense of it?
ok. so you have about 70 components or so. each with a header and a .cc average of about 200+ lines of code per component. (could have been a lot worse; imagine your plight with 16 components with about 1000 lines of code per component).
you could start by making a dependency graph of these components. compile a component a.cc
with a -MMD
switch to get a.d
which lists its dependecies. compile all components this way and prepare the dependency graph out of information in the .d
files.
now, scan through components which are at the lowest level in the dependency graph (those that have no other dependencies) to get an overall idea of what they do. and move up level by level in the dependency hierarchy to see what the high level architecture is.
then, determine where the component you are going to write fits in in this hierarchy and focus on the sub-graph that involves this component.
> but I was wondering if anyone has this implemented?
many people have. google for Moller-Trumbore algorithm.
two other implementations:
http://jgt.akpeters.com/papers/Chirkov05/C2005.cpp.html (chirkov's c2005 algorithm)
http://geometryalgorithms.com/Archive/algorithm_0105/algorithm_0105.htm#intersect_RayTriangle() (sunday)
> dfference between Heap and free Store in C++
http://www.devx.com/tips/Tip/13757
http://www.research.att.com/~bs/bs_faq2.html#realloc
> const variables (i.e constants or literals get memory) , is there is separate area for them
> or they are allocated in the data region only.
they may not be allocated at all. as per the standard,
A pointer or reference to a cv-qualified type need not actually point
or refer to a cv-qualified object, but it is treated as if it does; ...Except that any class member declared mutable can be modified,
any attempt to modify a const object during its lifetime
results in undefined behavior.
a good compiler can optimize them away. eg.
int fun( int a )
{
static const int b = 7 ;
const int c = 3 ;
const int* pb = &b ;
const int* pc = &c ;
return a + *pb + *pc ;
}
>c++ -O3 -S -fomit-frame-pointer -c consts.cc
.file "consts.cc"
.text
.align 2
.p2align 4,,15
.globl _Z3funi
.type _Z3funi, @function
_Z3funi:
.LFB2:
movl 4(%esp), %eax
addl $10, %eax
ret
.LFE2:
.size _Z3funi, .-_Z3funi
.globl __gxx_personality_v0
.ident "GCC: (GNU) 4.2.1 20070719 [FreeBSD]"
the C++ Standard Library doesn't provide any facility to compose function objects using logical connectives. (SGI STL does have the adapters compose1 and compose2; perhaps that is what you intended to use).
such a facility is not planned for c++09 either; lambda functions and the bind library provide equivalent functionality with simpler syntax.
> is there any simple method...
yes. use the boost.lambda library http://www.boost.org/doc/libs/1_35_0/doc/html/lambda.html in c++98, lambda functions in c++09.
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#include <vector>
int main()
{
using namespace boost::lambda ;
std::vector<int> v( 5U, 8 ) ;
std::remove_if( v.begin(), v.end(), _1<6 && _1>2 ) ;
}
#include <algorithm>
#include <vector>
int main()
{
std::vector<int> v( 5U, 8 ) ;
std::remove_if( v.begin(), v.end(),
[]( int x ) { return x>2 && x<6 ; } ) ;
}
> Does extern "c" work only for C
yes, and only with c capitalized. extern "C" ...
however, an implementation can support linkage to other languages. eg. extern "FORTRAN" ...
7.5 - Linkage specifications [dcl.link]
-2- The string-literal indicates the required language linkage. The meaning of the string-literal is implementation-defined. ... When the string-literal in a linkage-specification names a programming language, the spelling of the programming language's name is implementation-defined. [Note: it is recommended that the spelling be taken from the document defining that language, for example Ada (not ADA) and Fortran or FORTRAN (depending on the vintage). The semantics of a language linkage other than C++ or C are implementation-defined. ]-3- Every implementation shall provide for linkage to functions written in the C programming language, "C" .... [Example:
complex sqrt(complex); // C++ linkage by default
extern "C" {
double sqrt(double); // C linkage
}
--- end example] - ISO/IEC 14882 : 1998(E)
> 3.6 * vector_a; why can I not implement this binary operator as a member operator of a class Vector?
you can, if the class Vector is your own class.
if not ( for example for standard containers ), you can overload this operator as a free function (not a member function). eg.
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>
template < typename T, typename A,
template< typename U, typename V > class container >
container<T,A> operator* ( const T& n,
const container<T,A>& cntr )
{
container<T,A> result ;
std::transform( cntr.begin(), cntr.end(),
std::back_inserter(result),
std::bind1st( std::multiplies<T>(), n ) ) ;
return result ;
}
template < typename T, typename A,
template< typename U, typename V > class container >
inline container<T,A> operator* ( const container<T,A>& cntr,
const T& n )
{ return n * cntr ; }
int main()
{
std::vector<double> v1(10,3.4) ;
std::vector<double> v2 = 3.6 * v1 ;
}
> If I want pedal to be a pure virtual function, how do I do that?
put an = 0 ;
at the end of the function declaration. and not in the definition (if you want to define it; it need not be defined).
> but virtuals have me kind of lost virtual
means: the function is to be called based on the run-time type of the object, not the compile-time type of the variable. eg.
#include <iostream>
#include <typeinfo>
struct base_class
{
virtual void virtual_foo() = 0 ; // pure
void nonvirtual_bar() …
> however we have written a wrapper around this and are setting our own values for these Macros
> #define ACS_HLINE TEXT('-')
have you rebuilt the library (libcurses or libncurses) with these wrappers?
and perhaps the macro should be just #define ACS_HLINE '-'
what is the default output locale on the machine?
are you using something like hline( std::cout.widen( '-' ), n ) ;
or whline( window, std::cout.widen( '-' ), n ) ;
to draw these lines?
#include <iostream>
#include <string>
#include <sstream>
template< typename T, std::size_t N >
bool read_line_into_array( T (&array)[N], std::istream& istm )
{
// returns true on success (line has exactly N items)
// an alternative would be to return the number of items read
std::string line ;
if( std::getline( istm, line ) )
{
std::istringstream sstm(line) ;
std::size_t i = 0 ;
while( ( i<N ) && ( sstm >> array[i] ) ) ++i ;
return (i==N) && (sstm>>std::ws).eof() ;
}
return false ;
}
int main()
{
int a[8] ;
std::cout << read_line_into_array( a, std::cin ) << '\n' ;
}
sortValues
is not a template member. you need to modify DO_SORT
#define DO_SORT(varName, a, b, c, d) (*(varName)).sortValues(a, b, c, d)
when you are sorting an array of char
, use MySort<char>
not MySort<char*>
//...
MySort<char> *myCharSorter = new MySort<char>();
DO_SORT(myCharSorter, charPt, 0, 5, sortFunction);
//...
using all these void* (java object?), preprocessor macros and non-standard extensions (__typeof__) is not good C++.
here is your program translated into C++ (with a minor bug fixed).
#include <cstdlib>
#include <iostream>
using namespace std;
template<class T>
class MySort
{
private:
public:
MySort(){};
~MySort(){};
void sortValues( T* value, int start, int size,
void (*functocall)(T*, T*));
//This method accepts a user-defined function and sorts the value.
//The pointer is expected to have more than just one value, so it will be an array of some type.
bool isSorted( const T* value, int start, int size)
{
for(int i = start; i < size-1 ; i++)
{
if(value[i] > value[i + 1])
return false;
}
return true;
};
};
template<class T>
void MySort<T>::sortValues( T* value, int start, int size,
void (*functocall)(T*, T*))
{
if(start < size)
{
while(!isSorted(value, start, size))
{
for(int i = start; i < size-1 ; i++)
{
T *left = value+i, *right = value+i+1 ;
(*functocall)((left), (right));
}
}
}
else
std::cerr << "Start point cannot be greater than the size!" ;
}
template< typename T > void sortFunction( T* arg1, T* arg2 )
{
if( *arg2 < *arg1 )
{
T temp = *arg1 …
1. for all points p in S
2. for all points q in S
3. if p != q
4. draw a line from p to q
5. if all points in S except p and q lie to the left of the line add the directed vector pq to the solution set
this does not seem be right. why don't you try it out by hand (paper and pencil) on a small set of 5 or so points?
if you want something simple, take a look at the gift wrapping algorithm (Jarvis march): http://en.wikipedia.org/wiki/Gift_wrapping_algorithm
//...
case 2:
cout << "what is the title of the game you would like to remove?\n";
cin >> game;
myIterator = find( games.begin(), games.end(), game ) ;
if ( myIterator != games.end() )
{
games.erase(myIterator);
}
break;
// ...
struct Silicon
{
Silicon( const char* n ) : _name(n) {}
const std::string& name() const { return _name ; }
/* ... */
private: const std::string _name ;
};
enum { MAD_HATTER=0, CHESHIRE_CAT=1, MARCH_HARE=2,
GRYPHON=3, LORY=4, N = 5 } ;
Silicon Si[N] = { "Mad_hatter", "Cheshire Cat", "March Hare",
"Gryphon", "Lory" } ;
Silicon& cheshire_cat = Si[ CHESHIRE_CAT ] ;
Silicon& gryphon = Si[ GRYPHON ] ;
int Lorina_Charlotte_Liddell = LORY ;
Silicon& lorina = Si[ Lorina_Charlotte_Liddell ] ;
for( int i=0 ; i<10 ; ++i )
numb2[i] = i%2 == 0 ? (i/2)*5 : i ;
> an algorithm better than FFT for getting large numbers(of the order of 10 power 30 or more)?
FFT multiplications are efficient when numbers are very large. the other popular multiplication algorithms are Karatsuba and Toom-3. http://gmplib.org/manual/Multiplication-Algorithms.html#Multiplication-Algorithms
in general Karatsuba is suitable for smaller numbers, Toom-3 for larger numbers and FFT for very large numbers. which is the most appropriate for a particular number depends on the processor.
for example, for a x86/pentium4/sse2 processor, GMP has determined the following thresholds for multiplication (in number of limbs: 32-bits per limb on this processor)
Karatsuba 18 limbs
Toom-3 139 limbs
FFT MODF 456 limbs
FFT 5888 limbs
from gmp-4.1.4/mpn/x86/pentium4/sse2/gmp-mparam.h
http://www.srcdoc.com/gmp_4.1.4/
> ...probably some gcc/g++ extension that was messing things up
> (which is obviously the only real possibility here).
it is not some gcc/g++ extension; it is POSIX man pause
http://node1.yo-linux.com/cgi-bin/man2html?cgi_command=pause(2)
> So I want to know is it possible to compile a code in such a way that if it is compiled
> on RHEL 5 machine, same compiled code should work on any other Linux distros?
the problem is caused by changes in the ELF binary format between RHEL4/FC5 and RHEL5/FC6 or later. (the hash section and the hash format for symbol resolution has changed).
while RHEL5/FC6 and newer can handle both types of hash format, only the classical 'sysv' format is supported by older versions.
to make elf binaries which are backward compatible, use the linker switch --hash-style=sysv
for example while compiling with g++, use -Wl,--hash-style=sysv
to make one line of your ladder:
#include <string>
std::string make_line( char X, std::size_t num_chars,
std::size_t num_spaces_on_left )
{
const char space = ' ' ;
return std::string( num_spaces_on_left, space ) +
std::string( num_chars, X ) ;
}
using c++09 variadic templates http://www.osl.iu.edu/~dgregor/cpp/variadic-templates.pdf
#include <iostream>
template < typename T > T largest( T first, T second )
{ return first > second ? first : second ; }
template < typename T, typename... U > T largest( T first, U... rest )
{ return largest( first, largest( rest... ) ) ; }
int main()
{
int n1=5, n2=7, n3=1 ;
std::cout << largest( n1, 4, n2 ) << '\n' ;
std::cout << largest( n1, 78, 3, n2, 12, n3 ) << '\n' ;
}
// compile with: g++43 -Wall -std=c++0x -pedantic -Werror myfile.cc
ok. and what output do you get if you add this line to CMeasurement::getSumMethodName
std::cout << "CMeasurement::getSumMethodName::this: " << this << '\n' ;
and print out the value of &meas
before the call? are these the same values as what gdb reports?
this is what the C++ standard specifies about the layout (note that there are no separate specifications for struct and class)
Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified. Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions and virtual base classes.
and, earlier:
A structure is a class defined with the class-key struct; its members and base classes are public by default.
a class with just a single access specifier at the beginning and no virtual functions or base classes will be laid out as a struct is laid out in C.
> Where can I find this information?
a good (but dated) reference for object layout in C++: Inside the C++ Object Model by Stan Lippman http://www.informit.com/store/product.aspx?isbn=0201834545
> meas is an instance of CMeasurement and class CMeasurement is not derived from anything
in that case, it is either a horrible gdb/gcc version mismatch or (horror) the stack frame getting trashed.
by any chance, are you compiling without -g
or with -fomit-frame-pointer
? and are you handling signals anywhere in your code?