NathanOliver, thank you very much!
In additions to an assembly view, it has ICC and several versions of the GNU and LLVM implementations.
NathanOliver, thank you very much!
In additions to an assembly view, it has ICC and several versions of the GNU and LLVM implementations.
once you get into a mindset of using const keyword like that it just becomes natural no matter how non or complex the method is.
Yes. Yes.
In this example, the notion that the const-qualification may somehow 'allow the compiler to perform some extra optimisations' was true in some prehistoric era. If the entire context of use of an object is visible to the compiler (ie. the const-qualified object is not aliased, is not at namespace scope with external linkage, is not a parameter of a non-inline, non-template function with external linkage, etc.), it knows everything about what is going on with that object. It is a lot better at static-flow analysis than most programmers; and the "as-if" rule allows it to rewrite the code.
http://en.cppreference.com/w/cpp/language/as_if
C++11 deprecated the use of the keyword register
- compilers know what would be optimally placed in a register better than programmers; for about twenty years or so, they have been just ignoring the register
keyword as an optimisation hint. Just as they have been ignoring inline
as an optimisation hint.
const
in a purely local context is for the programmer; it makes no difference to the optimiser.
As an example, with optimisations enabled, this code
namespace
{
unsigned int at_namespace_scope_with_internal_linkage = 0 ;
}
int foobar()
{
at_namespace_scope_with_internal_linkage -= 100 ;
/* const omitted */ auto a = 52 ;
auto b = a / 2 ;
auto c = a + 5 ;
if( b < …
std::ofstream is not a CopyConstructible or CopyAssignable type. But it is MoveConstructible and MoveAssignable.
The CopyConstructor is explicitly deleted.
http://en.cppreference.com/w/cpp/io/basic_ofstream/basic_ofstream
The CopyAssignment operator is implicitly deleted.
http://en.cppreference.com/w/cpp/io/basic_ofstream/operator%3D
The CopyAssignment operator of routecaseBasedCDRFile
wold have been implicitly deleted if had not been declared. In this case, there is a user-defined CopyAssignment operator which does not assign to the std::ofstream member, but copies the state of all the other members, and therefore leaves the object in an invalid state.
Tip: Rule of zero http://en.cppreference.com/w/cpp/language/rule_of_three
#include <iostream>
#include <fstream>
#include <fstream>
#include <vector>
#include <type_traits>
struct A // MoveConstructible, MoveAssignable, not CopyConstructible, not CopyAssignable
{
explicit A( std::string path ) : file(path) {}
A( std::ofstream&& stm ) : file( std::move(stm) ) {} // transfer ownership of the stream
void test_it() { file << "output from A #" << id << '\n' ; }
std::ofstream file ; // std::ofstream is Moveable, but it is not Copyable
// copy constructor of A is implicitly deleted
// move constructor of A is implicitly defaulted
// copy assignment of A is implicitly deleted
// move assignment of A is implicitly defaulted
int id = seq_no++ ;
static int seq_no ;
};
int A::seq_no = 0 ;
int main()
{
std::cout << std::boolalpha
<< "MoveConstructible? " << std::is_move_constructible<A>::value << '\n'
<< "CopyConstructible? " << std::is_copy_constructible<A>::value << '\n'
<< "MoveAssignable? " << std::is_move_assignable<A>::value << '\n'
<< "CopyAssignable? " << std::is_copy_assignable<A>::value << "\n\n" ;
std::vector<A> seq ;
seq.emplace_back( "out0.txt" …
15. Use const proactively.
Summary
const is your friend. Immutable values are easier to understand, track, and reason about, so prefer constants over variables wherever it is sensible and make const your default choice when you define a value. It's safe, it's checked at compile time,
and it's integrated with C++'s type system. ...
Discussion
Constants simplify code because you only have to look at where the constant is defined to know its value everywhere. Consider this code:
void Fun( vector<int>& v)
{ //...
const size_t len = v.size();
//... 30 more lines ...
}
When seeing len's definition above, you gain instant confidence about len's semantics throughout its scope (assuming the code doesn't cast away const, which it should not do). It's a snapshot of v's length at a specific point. Just by looking up one line of code, you know len's semantics over its whole scope. Without the const, len might be later modified, either directly or through an alias. Best of all, the compiler will help you ensure that this truth remains true.
...
From: 'C++ Coding Standards: 101 Rules, Guidelines, and Best Practices' by Sutter and Alexandrescu
Trustworthy (and succinct) recommendations:
http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list
https://isocpp.org/get-started
'What is the best book to learn C++ from?' in https://isocpp.org/wiki/faq/how-to-learn-cpp
Use an enumeration http://en.cppreference.com/w/cpp/language/enum
Something like:
#include <iostream>
#include <string>
enum class choice_t : std::size_t { one = 1, two = 2 /* ... */, invalid = std::size_t(-1) };
std::ostream& operator << ( std::ostream& stm, choice_t c )
{
std::cout << "choice_t::" ;
static const std::string text[] = { "invalid", "one", "two", /* ... */ } ;
std::size_t v = std::size_t(c) ;
if( v >= sizeof(text) / sizeof( text[0] ) ) v = 0 ; // invalid choice
return stm << text[v] ;
}
std::istream& get_choice( std::istream& stm, choice_t& choice )
{
std::string c ;
if( stm >> c )
{
if( c == "1" || c == "one" || c == "choice1" ) choice = choice_t::one ;
else if( c == "2" || c == "two" || c == "choice2" ) choice = choice_t::two ;
// else if ...
else
{
choice = choice_t::invalid ; // invalid input
stm.clear( std::ios::failbit ) ; // force the stream into a failed state
}
}
return stm ;
}
int main()
{
std::cout << "\nPlease enter 'choice1' for pattern A or 'choice2' for pattern B: " ;
choice_t choice ;
get_choice( std::cin, choice );
switch(choice)
{
case choice_t::one:
std::cout << "your choice is: " << choice << " => pattern A\n" ;
// ...
break ;
case choice_t::two:
std::cout << "your choice is: " << choice << " => pattern B\n" ;
// ...
break ;
// case ...
default: std::cout << "this is an invalid choice (" << …
when i run the program , its keeps waiting
The proram engenders undefined behaviour; C++ has nothing to say about what its observable behaviour ought to be.
Using unsigned integer types for n
and i
would make the program constructs well-defined. However, it would still be 'computationally horrendous'.
Avoiding the expensive convert-to-string/check-for-substring would make it less horrendous; changing the type of n
from std::uint32_t
to std::uint16_t
would make it tractable.
Also, limiting the output to a finite number:
#include <iostream>
#include <cstdint>
#include <iomanip>
#include <limits>
bool has_digits_666( unsigned int number )
{
while( number > 665 )
{
if( number%1000 == 666 ) return true ;
number /= 10 ;
}
return false ;
}
int main()
{
std::uint16_t n = 2 ; // unsigned 16-bit wide integer
int cnt = 50 ;
for( unsigned int i = 0 ; cnt > 0 ; ++i ) // unsigned
{
if( has_digits_666(i) )
{
if( n == 1 )
{
constexpr int width = std::numeric_limits<int>::digits10 + 3 ;
std::cout << std::setw(width) << i << ' ' ;
if( --cnt % 5 == 0 ) std::cout << '\n' ; // 5 numbers per line
}
--n ;
}
}
}
It still performs a very large number of computations:
real 0m15.834s
user 0m15.833s
sys 0m0.000s
Use thread storage duration for the singleton.
http://en.cppreference.com/w/cpp/language/storage_duration
struct A // per-thread singleton
{
static A& instance() ;
private:
A() { /* ... */ };
A( const A& ) = delete ; // non-copyable
A( A&& ) = delete ; // non-moveable
};
A& A::instance() // Meyer's singleton
{
thread_local static A singleton ; // one singleton per thread
return singleton ;
}
This is an infinite loop: for( int i = 0, n = 2; ; ++i ) { /* ... (no break statement) */ }
A missing condition makes the implied while clause equivalent to while(true)
.
At some point of time, when i
becomes equal to std::numeric_limits<int>::max()
, ++i
will cause a signed integer overflow.
When n
becomes equal to std::numeric_limits<int>::min()
, n -= 1
will also trigger a signed integer overflow.
Don't know what happens in Java, but in C++, signed integer overflow engenders undefined behaviour.
Change the type of i
and n
to unsigned int
and the program is well-formed (though the infinite loop still remains). Unsigned integers obey the laws of arithmetic modulo 2^n
where n
is the number of bits in the value representation of the unsigned integer.
The keys in the map are const objects: const std::string
; they can't be modified directly inside the map.
Something like this, perhaps:
#include <iostream>
#include <map>
#include <string>
#include <cctype>
std::string to_lower( const std::string& str )
{
std::string lc ;
for( char c : str ) lc += std::tolower(c) ;
return lc ;
}
std::map< std::string, std::string > to_lower( const std::map< std::string, std::string >& map )
{
std::map< std::string, std::string > lc ;
for( const auto& pair : map ) lc.emplace( to_lower(pair.first), to_lower(pair.second) ) ;
return lc ;
}
int main()
{
std::map< std::string, std::string > the_sms_codes
{
{ ".02", "Your (or my) two cents worth" },
{ "10X", "Thanks" },
{ "2MI", "Too much information"},
{ "2U2", "To You Too" },
{ "4COL", "For Crying Out Loud" }
};
the_sms_codes = to_lower(the_sms_codes) ;
for( const auto& pair : the_sms_codes ) std::cout << pair.first << " - " << pair.second << '\n' ;
}
http://coliru.stacked-crooked.com/a/a8002a215a00beca
Or initialise them as lower case strings:
std::map< std::string, std::string > the_sms_codes
{
{ to_lower(".02"), to_lower("Your (or my) two cents worth") },
{ to_lower("10X"), to_lower("Thanks") },
// ...
};
The File System TS was published a couple of days back.
http://www.iso.org/iso/catalogue_detail.htm?csnumber=63483
Final Draft: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf
It is just a TS, so: 'This Technical Specification is applicable only to vendors who wish to provide the interface it describes.'
'Starting in 2012, the committee has transitioned to a "decoupled" model where major pieces of work can progress independently from the Standard itself and be delivered as separate TS's. Vendors can choose to implement these, and the community can gain experience with the std::experimental version of each feature.' - https://isocpp.org/std/status
Don't know about Turbo C++. This is standard C++; it may work in Turbo C++ too.
// open the source file for input (text)
std::ifstream srce_file( "G:/one/file.txt" ) ;
// or "G:\\one\\file.txt" if it is a really old version of Windows
// check for is_open() elided for brevity
// open the destination file for output (text),
// truncate if it exists, create new otherwise
std::ofstream dest_file( "C:/tc/file.txt" ) ;
// copy file
dest_file << srce_file.rdbuf() ;
<cerrno>
defines several standard integer error codes (integer constant expressions with type int
).
For instance, ENOENT for 'No such file or directory'
http://en.cppreference.com/w/cpp/error/errno_macros
<system_error>
gives us the scoped enum std::errc
For instance, std::errc::no_such_file_or_directory
http://en.cppreference.com/w/cpp/error/errc
<system_error>
also has the class std::error_code
. Objects of this type can be created from an error code enum and std::error_code::::message()
returns a string containing the error message.
http://en.cppreference.com/w/cpp/error/error_code/message
ScheduleFile mySchedule();
This is the declaration of a nullary function returning a prvalue of type ScheduleFile
See: https://en.wikipedia.org/wiki/Most_vexing_parse
int main() {
// ScheduleFile mySchedule(); // declare a function
ScheduleFile mySchedule ; // define a default initialised object
}
The canonical C++ way is to use templated callbacks in conjunction with:
wrapping the call in a polymorphic call wrapper std::function<>
and currying with std::bind()
http://en.cppreference.com/w/cpp/utility/functional/function
http://en.cppreference.com/w/cpp/utility/functional/bind
Sample code:
http://coliru.stacked-crooked.com/a/8d4283e68de561cf
http://rextester.com/VBNT79084
#include <iostream>
#include <limits>
#include <stdexcept>
#include <algorithm>
#include <cassert>
// algorithm from 'Hacker's Delight' by Henry S. Warren
// http://www.amazon.com/dp/0201914654
unsigned int plus( unsigned int a, unsigned int b )
{
auto carry = a & b;
auto sum = a ^ b;
while( carry != 0 )
{
const auto carry_shl = carry << 1 ;
carry = sum & carry_shl ;
sum ^= carry_shl ;
}
return sum ;
}
// Note: This assumes that the signed integer value representation is two's complement
// Two's complement is almost universally used, though he C++ standard allows any
// appropriate signed integer representation.
// For instance, one's complement and sign-and-magnitude representations would be conforming
int signed_plus( int a, int b )
{
const long long aa = a ;
long long result = aa + b ;
if( result < std::numeric_limits<int>::min() || result > std::numeric_limits<int>::max() )
throw std::out_of_range( "signed integer overflow!" ) ;
return int( plus(a,b) ) ;
}
int main()
{
const int test[][2] { {12345678,0}, {-12345678,0}, {12345678,67890}, {12345678,-67890}, {-12345678,67890}, {-12345678,-67890} } ;
for( const auto& arr : test )
{
int x = arr[0] ;
int y = arr[1] ;
std::cout << x << " + " << y << " == " << x+y << " == " << signed_plus(x,y) << '\n' ;
std::swap(x,y) ;
std::cout << x << " + " << y << " == " << x+y << " == " << signed_plus(x,y) << '\n' ;
assert( ( (x+y) == …
To search for a pattern in a string, use the C++ regular expression library.
Tutorial:
https://solarianprogrammer.com/2011/10/12/cpp-11-regex-tutorial/
http://www.informit.com/articles/article.aspx?p=2079020
The simplest way to run code asynchronously, and retrieve the result of the asynchronous operation, is to use std::async()
.
Tutorial:
https://solarianprogrammer.com/2012/10/17/cpp-11-async-tutorial/
http://www.drdobbs.com/cpp/c11s-async-template/240001196
Once you have read up on these two, writing the code is surprisingly easy.
Here's a snippet to get you started:
#include <iostream>
#include <string>
#include <regex>
#include <vector>
#include <fstream>
#include <future>
bool match( std::string line, std::string server_name, std::string user_name )
{
static const std::string number = "\\d+" ;
// see: http://en.cppreference.com/w/cpp/regex/ecmascript
// (beginning of line),server_name,number,number,user_name, ... (end of line)
const std::regex pattern( '^' + server_name + ',' + number + ',' + number + ',' + user_name + ",.+$" ) ;
// http://en.cppreference.com/w/cpp/regex/regex_match
return std::regex_match( line, pattern ) ;
}
std::vector<std::string> filter_lines( std::string logfile_name, std::string server_name, std::string user_name )
{
std::vector<std::string> result ;
std::ifstream file(logfile_name) ;
std::string line ;
while( std::getline( file, line ) ) if( match( line, server_name, user_name ) ) result.push_back(line) ;
return result ;
}
int main()
{
const std::string server_name = "XY" ;
const std::string user_name = "ABCDEF" ;
// http://en.cppreference.com/w/cpp/thread/future
using future_type = std::future< std::vector<std::string> > ;
std::vector<future_type> futures ;
//
for( std::string logfile_name : { "a.log", "b.log", "c.log", "d.log", "e.log" } )
futures.push_back( std::async( std::launch::async, filter_lines, logfile_name, server_name, user_name ) ) ;
// http://en.cppreference.com/w/cpp/thread/async
std::vector<std::string> log_records ;
for( auto& …
compile error : no matching member function for call to 'insert'
There is no error in the posted code (once the missing headers are added).
Since C++11, insert()
and erase()
on standard constainers accept const_iterators
.
http://en.cppreference.com/w/cpp/container/vector/insert
http://en.cppreference.com/w/cpp/container/vector/erase
Note: this does not break legacy code. The IS requires that for a standard container, there must be an implicit converstion from iterator
to const_iterator
.
You appear to be using an old version of libstdc++ which is still in legacy mode wrt this.
LLVM and GNU: http://coliru.stacked-crooked.com/a/51d6e6b2a90106fc
Microsoft: http://rextester.com/JRJP63287
Book: The C++ Standard Library: A Tutorial and Reference (2nd Edition) by Josuttis
http://www.amazon.com/Standard-Library-Tutorial-Reference-2nd/dp/0321623215
Online reference: http://en.cppreference.com/w/
Offline archive: http://en.cppreference.com/w/File:html_book_20141118.zip
GNU specific, and worth studying merely for the elegance of the design.
(Note: it violates ODR, but the implementation is allowed to provide well-defined semantics for undefined behaviour.)
<begion quote>
The following goals directed the design of the libstdc++ debug mode:
Correctness: <...>
Performance: <...>
Usability: <...>
Minimize recompilation: While it is expected that users recompile at least part of their program to use debug mode, the amount of recompilation affects the detect-compile-debug turnaround time. <...>
There are several levels of conformance to this requirement, each with its own usability and implementation characteristics. In general, the higher-numbered conformance levels are more usable (i.e., require less recompilation) but are more complicated to implement than the lower-numbered conformance levels.
4. Per-use recompilation: The user must recompile the parts of his or her application and the C++ libraries it depends on where debugging should occur, and any other code that interacts with those containers. This means that a set of translation units that accesses a particular standard container instance may either be compiled in release mode (no checking) or debug mode (full checking), but must all be compiled in the same way; a translation unit that does not see that standard container instance need not be recompiled. This also means that a translation unit A that contains a particular instantiation (say, std::vector<int>) compiled in release mode can be linked against a translation unit B that contains the same …
is it used to substitute constructor?
Yes. An exception-safe and (usually) more efficient substitute.
This function is typically used to replace the construction
std::shared_ptr<T>(new T(args...))
of a shared pointer from the raw pointer returned by a call to new.In contrast to that expression,
std::make_shared<T>
typically allocates memory for theT
object and for thestd::shared_ptr
's control block with a single memory allocation (this is a non-binding requirement in the Standard), wherestd::shared_ptr<T>(new T(args...))
performs at least two memory allocations.Moreover, code such as
f(std::shared_ptr<int>(new int(42)), g())
can cause a memory leak ifg
throws an exception becauseg()
may be called afternew int(42)
and before the constructor ofshared_ptr<int>
. This doesn't occur inf(std::make_shared<int>(42), g())
, since two function calls are never interleaved.
- http://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared
The input consists of two numbers X and Y ( - 10^12 <x, y< 10^12).
Well, then the essence of this exercise is to ask the student to determine and use a suitable signed integer type that can hold integers having 13 decimal digits.
(The types int
or long int
may be inadequate.)
#include <iostream>
int main()
{
constexpr auto upper_bound = 1'000'000'000'000 ; // C++14 literal
// constexpr auto upper_bound = 1000000000000 ; // C++11
constexpr auto lower_bound = -1'000'000'000'000 ;
// integer_type is an alias for a signed integer type
// which can hold integers with 13 decimal digits
// http://www.stroustrup.com/C++11FAQ.html#decltype
using integer_type = decltype(9'999'999'999'999) ;
integer_type x = 0 ;
std::cin >> x ; // if input fails, x would be set to zero
integer_type y = 0 ;
std::cin >> y ; // do nothing if std::cin is in a failed state
if( x > lower_bound && y < upper_bound )
{
char relation = '=' ;
if( x < y ) relation = '<' ;
else if( y < x ) relation = '>' ;
std::cout << x << ' ' << relation << ' ' << y << '\n' ;
}
}
First, make sure that you understand ODR and linkage
http://en.cppreference.com/w/cpp/language/definition
http://en.cppreference.com/w/cpp/language/storage_duration
The build mechanism is implementation specific.
A Tutorial revealed via a web search:
http://www.bogotobogo.com/cplusplus/libraries.php
(For the record: I do not agree with the 'whenever possible' in "Use dynamic libraries instead of static libraries whenever possible!")
#include <iostream>
int main()
{
int x ;
std::cin >> x ; // if input fails, x would be set to zero
int y = 0 ;
std::cin >> y ; // do nothing if std::cin is in a failed state
// there is no need to check that x and y are valid integers
char relation = '=' ;
if( x < y ) relation = '<' ;
else if( y < x ) relation = '>' ;
std::cout << x << ' ' << relation << ' ' << y << '\n' ;
}
The file is not huge (molecules); consider reading the entire file into a data structure in memory. Perform the look ups in memory, and if the data is modified, write it back into the file at the end.
For instance: http://coliru.stacked-crooked.com/a/30d9483adc21fb9a
#include <iostream>
#include <locale>
#include <iomanip>
// http://en.cppreference.com/w/cpp/locale/numpunct
struct space_separated : std::numpunct<char>
{
// http://en.cppreference.com/w/cpp/locale/numpunct/thousands_sep
virtual char do_thousands_sep() const override { return ' ' ; } // separate with spaces
// http://en.cppreference.com/w/cpp/locale/numpunct/grouping
virtual std::string do_grouping() const override { return "\3"; } // in groups of 3 digits
};
int main()
{
// http://en.cppreference.com/w/cpp/io/basic_ios/imbue
std::cout.imbue( std::locale( std::locale( "en_GB.utf8" ), new space_separated ) ) ;
// http://en.cppreference.com/w/cpp/io/ios_base/getloc
const auto stdout_locale = std::cout.getloc() ;
// http://en.cppreference.com/w/cpp/locale/use_facet
// http://en.cppreference.com/w/cpp/locale/moneypunct
const auto& mp_iternational = std::use_facet< std::moneypunct<char,true> >( stdout_locale ) ;
const auto& mp_brief = std::use_facet< std::moneypunct<char> >( stdout_locale ) ;
const double pounds = 1234567.89 ;
const long double pence = pounds * 100 ;
std::cout << std::fixed << std::setprecision(2) << "space separated, number: " << pounds << "\n\n"
<< "space separated, trailing currency, international: " << pounds << ' ' << mp_iternational.curr_symbol() << "\n\n"
<< "space separated, trailing currency, brief: " << pounds << mp_brief.curr_symbol() << "\n\n"
<< "locale default, international: " << std::showbase << std::put_money( pence, true ) << "\n\n"
<< "locale default, brief: " << std::put_money(pence) << '\n' ;
// http://en.cppreference.com/w/cpp/io/manip/put_money
}
The Microsoft implementation includes the draft TR2 filesystem library.
(With other compilers, boost::filesystem
which privides like functionality can be used.)
#include <iostream>
#include <string>
#include <vector>
#include <filesystem>
namespace fs = std::tr2::sys ;
std::vector<std::wstring> files_in_directory( fs::wpath path = L".", bool recursive = true )
{
std::vector<std::wstring> files ;
try
{
if( fs::exists(path) ) files.push_back( fs::system_complete(path) ) ;
if( fs::is_directory(path) )
{
using iterator = fs::basic_directory_iterator < fs::wpath > ;
for( iterator iter(path) ; iter != iterator() ; ++iter )
{
files.push_back( fs::system_complete( iter->path() ) ) ;
if( recursive )
for( const std::wstring& p : files_in_directory( iter->path() ) )
files.push_back( std::move(p) ) ;
}
}
}
catch( const std::exception& ) { /* error */ }
return files ;
}
int main()
{
for( const std::wstring& path : files_in_directory( L"C:\\Windows", false ) )
std::wcout << path << '\n' ;
}
f i have like getline and if it cant get anything, the program will obviously crash/not build
No. std::getline()
first clears the string and if no characters were extracted (not even the discarded delimiter), sets the failbit on the stream.
if( std::getline( stm, line ) ) \\ if at least one character was extracted
#include <iostream>
#include <fstream>
int main()
{
const char* const path_to_file = __FILE__ ; // put the actual path here
std::ifstream file(path_to_file) ;
if( !file.is_open() ) std::cerr << "could not open file\n" ;
else if( file.peek() == EOF ) std::cout << "file is empty\n" ;
else std::cout << "file contains at least one character\n" ;
}
I think it must be since it all occurs between sequence points.
Sequence point rules were there prior to C++11. Now, those rules have been superceded by sequenced-before rules.
The question: does i++ + ++i;
engender undefined behaviour is of relevance if and only if i
is of a scalar type.
If i
is of a user-defined type, ++i
and i++
are function calls; the evaluations of the sub-expressions are indeterminately sequenced. This means that they may be evaluated in any order; but the two evaluations will never interleave even on a multi-core processor. Indeterminately sequenced does not imply undefined behaviour.
If i
is a scalar, the evaluations are unsequenced and unsequenced side effects on a scalar leads to undefined behaviour.
Is double pre-incrementing undefined behavior? Like ++++x or even ++++++++x.
Assuming that x is a scalar, these are of interest:
If x is not of type bool
, the expression ++x is equivalent to x+=1 - IS
The behavior of an expression of the form E1 op = E2
is equivalent to E1 = E1 op E2
except that E1 is evaluated only once.
AFAIK:
#include <iostream>
int main()
{
int i = 1 ;
struct A
{
int i ;
int j ;
A( int a, int b ) : i(a), j(b) {}
A& operator++() { return *this ; };
A operator++(int) { return *this ; };
A operator+ (A) { return *this ; }
};
/////////// well-defined behaviour //////////////////////
i = i + …
am trying to generate prime numbers well in excess of 1Gbyte of mem.
It does not matter what knid of contortions we go thrugh to allocate memory - new, malloc, HeapAlloc, GlobalAlloc, VirtualAlloc, MapViewOfFile ... - we are fundamentaly limited by the virtual address space that we have. With MinGW32, the total amount of memory available for user land use is 2 GB (could have been 3 GB if MinGW was built with /largeaddressaware). Of this 2GB, a chunk is taken away by the executable image, system and language libraries etc.
Repeat: If dynamic memory requirements are well in excess of 1 GB, and you are on a 64-bit windows platform, switch to MinGW64.
#include <iostream>
int main()
{
std::cout << "GCC version is: " << __GNUC__ // major version
<< '.' << __GNUC_MINOR__ // minor version
<< '.' << __GNUC_PATCHLEVEL__ // patch
<< '\n' ;
}
What other alternatives for Windows in memory allocation?
Use smart_pointers, std::string, std::vector<> etc. instead of raw pointers.
http://msdn.microsoft.com/en-in/library/hh279674.aspx
Unless the program has exhorbitant memory needs, this would fix the problem.
If dynamic memory requirements are well in excess of 1 GB, and you are on a 64-bit windows platform, switch to MinGW64.
http://nuwen.net/mingw.html
Even if you switch to MinGW64, use smart_pointers, std::string, std::vector<> etc. instead of raw pointers.
#include <iostream>
#include <string>
#include <cstring>
std::string replace( const char* str, // input string; make that const-correct,
std::size_t sz_str, // length of input string
std::size_t start, // start pos of substring to be replaced
std::size_t length, // length of substring to be replaced,
const char* new_substr, // string to replace the substring, made const-correct
std::size_t sz_substr ) // length of string to replace the substring,
{
std::string result( str, str+start ) ; // initialize with chars before the substring
result.append( new_substr, sz_substr ) ; // append the new substring
result.append( str+start+length, str+sz_str ) ; // append chars after the substring
return result ;
}
std::string replace( const char* str, // input string; make that const-correct,
std::size_t start, // start pos of substring to be replaced
std::size_t length, // length of substring to be replaced,
const char* new_substr ) // string to replace the substring, made const-correct
{
if( str == nullptr ) return new_substr ? new_substr : "" ;
auto sz_str = std::strlen(str) ;
start = std::min( start, sz_str - 1 ) ;
length = std::min( length, sz_str-start ) ;
if( new_substr == nullptr ) return replace( str, sz_str, start, length, nullptr, 0 ) ;
else return replace( str, sz_str, start, length, new_substr, std::strlen(new_substr) ) ;
}
int main()
{
std::cout << replace( "nhrnsubstr6", 4, 6,"jic" ) << '\n'
<< replace( "substrjic6", 0, 6,"nhrn" ) << '\n'
<< replace( "substrnhrnjic6", 0, 6,"" ) << '\n'
<< replace( "nhrnjic6substr", 8, 100,"" ) << '\n'
<< replace( "nhrnsubstr6jic", 4, 6,"" ) …
Read this first: http://www.cplusplus.com/articles/Gw6AC542/
Take your time; make sure you have understood it.
The structure of your code should be something like this:
file game.h
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED
#include <string>
#include <vector>
class adventure ; // declare
class game
{
struct PlayerScore {
std::string name;
int score;
};
std::vector<PlayerScore> scores ;
public:
// ...
void addtoHallofFame( adventure a ) ; // declare, do not define
// ...
};
#endif // GAME_H_INCLUDED
file adventure.h
#ifndef ADVENTURE_H_INCLUDED
#define ADVENTURE_H_INCLUDED
#include <vector>
#include <string>
class game ; // declare
class adventure {
int score = 0 ;
game& g ;
public:
adventure( game& the_game ) : g(the_game) { /* ... */ }
// ...
inline int getScore() const { return score ; }
void update( const std::vector<std::string>& arr ) ; // declare, do not define
// ...
static const std::string quit_msg ; // this is just a declaration
};
#endif // ADVENTURE_H_INCLUDED
file game.cpp
#include "game.h"
#include "adventure.h" // class adventure is now defined
// ...
void game::addtoHallofFame( adventure a ) // define
{
int adventureScore = a.getScore();
std::string playerName;
// ...
PlayerScore p = { playerName, adventureScore } ;
scores.push_back(p) ;
}
// ...
file adventure.cpp
#include "adventure.h"
#include "game.h" // class game is now defined
// ...
const std::string adventure::quit_msg = "quit" ; // define the static member in the cpp file
void adventure::update( const std::vector<std::string>& arr )
{
if( !arr.empty() && arr.front() == quit_msg )
// ...
g.addtoHallofFame(*this) ; …
The problem with
{
Game g;
g.addtoHallofFame(*this);
}
is that g
is a local variable at block scope (automatic storage duration); it will be destroyed when the scope is exited from.
One option would be to make vector<PlayerScore> scores;
a static member of Game
; this is logical if there can be only one game in progress at a time.
Another is to keep a reference to the associated Game
as a member in the Adventure
object.
Or to pass a reference to the associated Game
as a parameter to update()
// favour a std::vector<std::string> or std::array< std::string, N > over raw arrays
// void Adventure::update( string arr[], Game& g )
void Adventure::update( const vector<string>& arr, Game& g )
{
if ( !arr.empty() && arr[0] == "quit" ) // ideally avoid the magic constant "quit"
{
g.addtoHallofFame(*this);
}
}
can someone help knowing the difference between
> char *st="myname";
> char st[]="myname";
"myname"
is a narrow string literal; in C++, A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration. - IS
So, with "myname"
we have an an lvalue of type array of 7 const char. The life-time of this array is the duration of the program.
This array can be implicitly converted to a prvalue of of type “pointer to const char”; the result of the conversion is a pointer to the first element of the array. For compatibility with C code, C++98 specified:
A string literal that is not a wide string literal can be converted to an rvalue of type “pointer to char” ... [Note: this conversion is deprecated.]
C++11 simply dropped the above clause from the IS, and has this in Annex C (Compatibility):
Change: String literals made const
The type of a string literal is changed from “array of char” to “array of const char.” The type of a char16_t string literal is changed from ...
Rationale: This avoids calling an inappropriate overloaded function, which might expect to be able to modify its argument.
Effect on original feature: Change to semantics of well-defined feature.
Difficulty of converting: Syntactic transformation. The fix is to add a cast:
> char* p = "abc"; // valid in C, invalid in …
C++ input streams have two different modes of input. When we use the >> operator, we are doing formatted input; when we don't (for instance we do a std::getline()
or a std::cin.getline()
) we are doing unformatted input.
The formatted input operator >> discards leading white space, and stops reading when it encounters a white space (or invalid input). Unformatted input on the other hand, does not discard leading whitespace.
Now let us say, we want to read an int (using formatted input) and a string (using unformatted input) from stdin. We write:
int number ;
std::string text ;
std::cin >> number ;
std::getline( std::cin, text ) ;
We run the program and enter 12345<newline> on stdin. std::cin >> number ;
reads 12345 into number and leaves the <newline> in the input buffer. The program continues with std::getline( std::cin, text ) ;
The getline()
sees that the input buffer is not empty, so it does not wait for any input to be entered. It returns immediately after reading an empty string, and extracting the <newline> in the buffer and throwing it away.
One solution to the problem is not to mix formatted and unformatted input.
Another is to make the stream discard trailing white space left by the formatted input operation. This can be done by:
int number ;
std::string text ;
std::cin >> number ;
std::cin.ignore( 1024, '\n' ) ;
std::getline( std::cin, text ) ;
std::cin.ignore( 1024, '\n' ) ;
will extract and discard up …
#include <vector>
#include <string>
#include <iostream>
struct A
{
// see: http://www.stroustrup.com/C++11FAQ.html#uniform-init
// see: http://www.stroustrup.com/C++11FAQ.html#member-init
std::vector<std::string> activities {1} ; // vector with initial size 1 (contains one empty string)
// see: http://www.stroustrup.com/C++11FAQ.html#init-list
std::vector<std::string> animals { "panda", "lynx", "ibex" } ; // vector with 3 animals (strings)
std::vector<std::string> colours ;
// see: http://www.stroustrup.com/C++11FAQ.html#uniform-init
A() : colours { "cyan", "magenta", "yellow", "black" } {} // colours initialised with 4 colours (strings)
};
template < typename SEQUENCE >
void print( const SEQUENCE& seq, const char* name = "", std::ostream& stm = std::cout )
{
stm << name << ": [ " ;
// see: http://www.stroustrup.com/C++11FAQ.html#auto
// see: http://www.stroustrup.com/C++11FAQ.html#for
for( const auto& v : seq ) stm << '"' << v << "\" " ;
stm << "]\n" ;
}
int main()
{
A a ;
print( a.activities, "activities" ) ; // activities: [ "" ]
print( a.animals, "animals" ) ; // animals: [ "panda" "lynx" "ibex" ]
print( a.colours, "colours" ) ; // colours: [ "cyan" "magenta" "yellow" "black" ]
}
guess the C++ compiler doesn't, though. Do you think there is any specific reason for that
There is an explanation in the C Rationale
http://www.lysator.liu.se/c/rat/a.html
Re. portability:
Although it strove to give programmers the opportunity to write truly portable programs, the Committee did not want to force programmers into writing portably, to preclude the use of C as a ``high-level assembler'': the ability to write machine-specific code is one of the strengths of C. It is this principle which largely motivates drawing the distinction between strictly conforming program and conforming program (§1.7).
...A strictly conforming program is another term for a maximally portable program. The goal is to give the programmer a fighting chance to make powerful C programs that are also highly portable, without demeaning perfectly useful C programs that happen not to be portable. Thus the adverb strictly.
Re. Undefined behaviour:
The terms unspecified behavior, undefined behavior, and implementation-defined behavior are used to categorize the result of writing programs whose properties the Standard does not, or cannot, completely describe. The goal of adopting this categorization is to allow a certain variety among implementations which permits quality of implementation to be an active force in the marketplace as well as to allow certain popular extensions, without removing the cachet of conformance to the Standard.
...
Undefined behavior gives the implementor license not to catch certain program errors that are difficult to diagnose. It also identifies areas of …
Why the warning doesn't occur in C++?
The IS does not require that undefined behaviour must be diagnosed.
The macro #define msizeof(type) ((char*)(&type) - (char*)(&type - 1))
engenders undefined behaviour when used this way:
int main()
{
int x;
// msizeof(x) attempts to evaluate &x - 1
// *** this engenders undefined behaviour
printf("%u %u\n", msizeof(x), sizeof(x));
}
When an expression that has integral type is added to or subtracted from a pointer ...
<elided for brevity>
... If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.
In contrast, changing the macro to: #define msizeof(type) ((char*)(&type + 1) - (char*)(&type))
which attempts to evaluate &x + 1
eschews undefined behaviour because of the special provision:
For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.
#include <iostream>
#include <ctime>
namespace bday_utils {
namespace {
int bday = 0;
int bmonth = 0;
int byear = 0;
void get_dumbass_birthday() {
std::cout << "What is your bday (e.g. 4/15/1994) -> " ;
char slash ;
std::cin >> bmonth >> slash >> bday >> slash >> byear ;
}
void show_next_dumbass_birthday() {
const auto now = std::time(nullptr) ;
const auto& tm = *std::localtime( &now ) ;
const int temp = 11 - tm.tm_mon + bmonth ;
const int temp2 = tm.tm_mday - bday;
std::cout << "Your bday is " << temp << " months & " << temp2 << " days away\n" ;
}
}
}
int main()
{
bday_utils::get_dumbass_birthday();
bday_utils::show_next_dumbass_birthday();
}
sprout::string from the Sprout C++ Libraries may be of interest.
https://github.com/bolero-MURAKAMI/Sprout
#include <iostream>
#include <sprout/string.hpp>
int main()
{
constexpr auto hello = sprout::to_string( "hello" ) ;
constexpr auto world = sprout::to_string( "world" ) ;
constexpr auto hello_world = hello + " " + world ;
static_assert( hello_world[5] == ' ', "" ) ;
static_assert( hello_world.find( "llo worl" ) == 2, "" ) ;
static_assert( hello_world.rfind( 'l' ) == hello_world.size() - 2, "" ) ;
static_assert( hello_world.find_first_of( "ord" ) == 4, "" ) ;
static_assert( hello_world.find_last_not_of( "old" ) == hello_world.size() - 3, "" ) ;
static_assert( hello_world.back() == *hello_world.rbegin(), "" ) ;
std::cout << hello_world.substr( 3, 5 ) << '\n' ; // lo wo
constexpr auto s137 = sprout::to_string( 137 ) ;
constexpr auto pi = sprout::to_string( double(22) / 7 ) ;
constexpr auto eqn = s137 + " * " + pi + " = " + sprout::to_string( 137 * double(22) / 7 ) ;
std::cout << eqn << '\n' ; // 137 * 3.142856 = 430.571429
static_assert( eqn <= hello_world, "" ) ;
constexpr auto hash = sprout::to_hash(eqn) ;
std::cout << hash << '\n' ; // 13698126077260970431
}
i tried this simple function but it won't compile
constexpr int multiply( int x, int y ){ return x*y ; }
The November 2013 CTP will compile it.
http://www.microsoft.com/en-us/download/details.aspx?id=41151&751be11f-ede8-5a0c-058c-2ee190a24fa6=True&fa43d42b-25b5-4a42-fe9b-1634f450f5ee=True
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main()
{
std::vector<int> seq { 4, 9, 2, 8, 1, 3, 0, 6, 7, 5} ;
const auto begin = std::begin(seq) ;
const auto end = std::end(seq) ;
std::cout << "smallest element: "
<< *std::min_element( begin, end ) << '\n' ;
std::cout << "position of smallest element: "
<< std::min_element( begin, end ) - begin << '\n' ;
constexpr std::size_t n = 5 ;
std::nth_element( begin, begin+n, end ) ;
std::cout << "the smallest " << n << " elements are: " ;
for( std::size_t i = 0 ; i < n ; ++i )
std::cout << seq[i] << ' ' ;
std::cout << '\n' ;
}
Typically <ios> will be included along with <iostream>, but it's not strictly portable to rely on that behavior.
The IS specifies that the header <iostream>
must include the header <ios>
27.4 Standard iostream objects [iostream.objects]
27.4.1 Overview [iostream.objects.overview]
Header <iostream> synopsis
#include <ios>
#include <streambuf>
#include <istream>
#include <ostream>
namespace std {
extern istream cin;
// etc.
}
Whether the output is going to (input is coming from) a file or not is determined by the dynamic type of the streambuf object, and not by the dynamic type of the stream object. (It is not unusual in C++ to do runtime redirection via the stream buffer.)
Discriminating on the dynamic type of the streambuf results in more robust code.
#include <iostream>
#include <fstream>
struct A { /* whatever */ };
struct B { /* whatever */ };
namespace detail_
{
std::ostream& puta( std::ostream& stm, A, std::false_type )
{ return stm << "write to non-file: A{ /* ... */ }" ; }
std::ostream& puta( std::ostream& stm, A, std::true_type )
{ return stm << "write to file: A{ /* ... */ }" ; }
std::ostream& putb( std::ostream& stm, B, std::false_type )
{ return stm << "write to non-file: B{ /* ... */ }" ; }
std::ostream& putb( std::ostream& stm, B, std::true_type )
{ return stm << "write to file: B{ /* ... */ }" ; }
}
std::ostream& operator<< ( std::ostream& stm, A a )
{
auto p = dynamic_cast<std::filebuf*>(stm.rdbuf()) ;
return p ? detail_::puta( stm , a, std::true_type{} ) :
detail_::puta( stm , a, std::false_type{} ) ;
}
std::ostream& operator<< ( std::ostream& stm, B b )
{
auto p = dynamic_cast<std::ofstream*>( std::addressof(stm) ) ;
return p ? detail_::putb( stm , b, std::true_type{} ) :
detail_::putb( stm , b, std::false_type{} ) ;
}
int main()
{
A a ;
B b ;
{
std::filebuf fbuf ;
fbuf.open( "some_file.txt", std::ios::out …
This is a canonical way to flatten out arrays of more than one (runtime) dimension. (The code below is for three dimensions):
#include <vector>
#include <memory>
template < typename T > struct array_3d_flat
{
array_3d_flat( std::size_t i, std::size_t j, std::size_t k,
const T& v = T() ) : data( i*j*k, v )
{
for( std::size_t m = 0 ; m < data.size() ; m += k )
inner.push_back( std::addressof( data[m] ) ) ;
for( std::size_t m = 0 ; m < inner.size() ; m += j )
outer.push_back( std::addressof( inner[m] ) ) ;
}
// moveable, non-copyable
array_3d_flat( const array_3d_flat<T>& ) = delete ;
array_3d_flat<T>& operator= ( const array_3d_flat<T>& ) = delete ;
array_3d_flat( array_3d_flat<T>&& ) noexcept = default ;
array_3d_flat<T>& operator= ( array_3d_flat<T>&& ) = default ;
T** operator[] ( std::size_t i ) { return outer[i] ; }
T& operator() ( std::size_t i, size_t j, size_t k )
{ return outer[i][j][k] ; }
const T** operator[] ( std::size_t i ) const ; // elided for brevity
const T& operator() ( std::size_t i, size_t j, size_t k ) const ; // elided
private:
std::vector<T**> outer ;
std::vector<T*> inner ;
std::vector<T> data ;
};
Compiled code is here: http://coliru.stacked-crooked.com/a/7c570672c13ca3bf
int main(){
vector<user> userDetails;
// string line;
string userName;
string password;
{
// local scope: we do not want to keep
// the stream for longer than necessary
ifstream readFile("userInfo.txt");
// while(getline(readFile,line)) {
// a line consists of just two ws-seperated tokens
// we can directly read them into userName and password
while( readFile >> userName >> password ) {
// stringstream iss(line);
// iss >> userName >> password;
// user userInfoDetails(userName,password);
// using the object anonymously makes for clearer code
userDetails.push_back( user(userName,password) );
}
// readFile.close();
// the destructor of the stream will close it
}
cout << "Before Deletion" << endl;
for ( /*int*/ std::size_t i =0; i<userDetails.size(); i++) {
cout << userDetails[i].getUserName() << " "
<< userDetails[i].getPassword() << "\n";
}
cout << " " << endl;
string name;
cout << "Enter User Name to delete: ";
cin >> name;
cout << " " << endl;
for (/*int*/ std::size_t i = 0; i<userDetails.size(); /* i++ */ ) {
if(userDetails[i].getUserName() == name){
// userDetails.erase(userDetails.begin() + i);
// if we do not need to maintain an ordered sequence
// this is the canonical way to remove an element
// cheaper than: userDetails.erase(userDetails.begin() + i);
std::swap( userDetails[i], userDetails.back() ) ;
userDetails.pop_back() ;
// break ; // uncomment if there are no duplicated names
}
else ++i ; // increment only if the element at i is not erased
// if we have erased the element at position i,
// a new element has come into that position;
// and we …
In the following small c++ program ...
Use std::string
instead?
#include <iostream>
#include <string>
int main( int argc, char* argv[] )
{
for( int i = 1 ; i <argc ; ++i )
{
const std::string arg = argv[i] ;
const auto rem = arg.size() % 3 ;
const auto nzeroes = rem ? 3-rem : 0 ;
const std::string sanitized_arg = std::string( nzeroes, '0' ) + arg ;
std::cout << arg << " => " << sanitized_arg << '\n' ;
}
}