Why executing this code:
// DefaultAny.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <exception>
using std::cout;
template<class T>
struct NoReturnPolicy
{
static void calculate(T& result, const T& source)
{
result = source;
}
};
template<class T>
struct ReturnPolicy
{
static T& calculate(T& result, const T& source)
{
result = source;
return result;
}
};
template<class T>
struct ThrowPolicy
{
static void check(T* ptr)
{
cout << "ThrowPolicy";
struct Nullptr: public std::exception{};
if(!ptr)
{
throw Nullptr("Nullptr not allowed");
}
}
};
template<class T>
struct NoThrowPolicy
{
static T* check(T* ptr)
{
cout << "NoThrowPolicy";
if(!ptr)
{
return nullptr;
}
else
{
return ptr;
}
}
};
/*
If pointer already points at
something no assignement is being done
*/
template<class T, class ThrowingPolicy>
struct NoAssignPolicy
{
static T* check(T* dest,const T*const src)
{
cout << "NoAssignPolicy";
if (!ThrowPolicy::check(dest))
{
dest = operator new(sizeof(T));
new (dest) T(*src);
}
}
};
template<class T,class ThrowingPolicy>
struct NoCheckPolicy
{
static void check(T* p)
{
cout << "NoCheckPolicy";
}
};
template<class T,class ThrowingPolicy>
struct CheckPolicy
{
static void check(T* p)
{
cout << "CheckPolicy";
ThrowingPolicy::check(p);
}
};
template<
class T,
class ThrowingPolicy = NoThrowPolicy<T>,
class CheckingPolicy = NoCheckPolicy<T,ThrowingPolicy>,
class AssigningPolicy = NoAssignPolicy<T,ThrowingPolicy>,
class ReturningPolicy = NoReturnPolicy<T>
>
struct BreadSlicer
{
BreadSlicer()
{
cout << "Type: " << typeid(T).name() << '\n';
cout << "ThrowingPolicy: " << ThrowingPolicy::check(0) << '\n'; //
//<<<---------The second call to cout makes output on my console:
//NoThrowPolicy:"NoSpace"ThrowingPolicy:"Space"000000
}
};
//The words NoSpace and Space do not actually appear in my console ;) and they are in the opposite order.
int _tmain(int argc, _TCHAR* argv[])
{
BreadSlicer<int> a;
return 0;
}
See comments in first struct above main.
This is the result of unspecified behavior. If you have:
cout << a() << b() << c() << endl;
The order of execution of a, b, and c is not defined (yes, their results are added to the cout stream in a predictable order, but execution of the functions is not in defined order).
If your question is why "NoThrowPolicy" gets output before "ThrowingPolicy", the answer is that there's no sequence point guaranteeing an ordering for the call to ThrowingPolicy::check(0) and the call to operator<<(cout, "ThrowingPolicy: "). C++ is allowed to call those functions in either order.
Related
I got to know that we can also pass template arguments to choose which function should execute. I found them good alternative to function pointers since function pointers has run time cost but template parameters does not. Also, template parameters can be made inline whereas function pointers are not.
Alright then, this is what I wrote to depict my understanding on it. I came close but missing some minor detail somewhere.
template<class T>
class String {
public:
T str;
String() { std::cout << "Ctor called" << std::endl; }
};
template<class T, class C>
int compare(const String<T> &str1,
const String<T> &str2) {
for (int i = 0; (i < str1.length()) && (i < str2.length()); ++i) {
if (C::eq(str1[i], str2[i])) {
return false;
}
}
return true;
}
template<class T>
class Cmp1 {
static int eq(T a, T b) { std::cout << "Cmp1 called" << std::endl; return a==b; }
};
template<class T>
class Cmp2 {
static int eq(T a, T b) { std::cout << "Cmp2 called" << std::endl; return a!=b; }
};
int main() {
String<std::string> s;
s.str = "Foo";
String<std::string> t;
t.str = "Foo";
compare<String<std::string>, Cmp1<std::string> >(s, t);
// compare(s, t);
}
Details of the code:
I have an class String, which take an parameter and create member function of that type.
I have an compare function, which takes two String& arguments. Comparison function is passed to it.
Cmp1 and Cmp2 are two compare functions.
compare<String<std::string>, Cmp1<std::string> >(s, t);
does not get compile here. I tried some other ways to call but in vain.
Looks like you want something like that:
#include <iostream>
#include <string>
template<class T>
class String {
public:
T str;
String() { std::cout << "Ctor called" << std::endl; }
};
template<class T, class C>
int compare(const String<T> &str1,
const String<T> &str2) {
for (int i = 0; (i < str1.str.length()) && (i < str2.str.length()); ++i) {
if (C::eq(str1.str[i], str2.str[i])) {
return false;
}
}
return true;
}
template<class T>
class Cmp1 {
public:
static int eq(T a, T b) { std::cout << "Cmp1 called" << std::endl; return a==b; }
};
template<class T>
class Cmp2 {
public:
static int eq(T a, T b) { std::cout << "Cmp2 called" << std::endl; return a!=b; }
};
int main() {
String<std::string> s;
s.str = "Foo";
String<std::string> t;
t.str = "Foo";
compare<std::string, Cmp1<char> >(s, t);
// compare(s, t);
}
code
Explanations:
You already have String in definition of compare, you need to just send T which is std::string in your case.
You are trying to go through entire std::string, in compare, so, now your code compiles.
You calling cmp on str[index], that is actually char, so you need to call cmp with char template argument.
[Edit: Turns out we don't even need reinterpret cast, making this even simpler]
This came up here and I found a better solution using reinterpret cast and shared pointer aliasing constructor. It allows both the ctor and dtor to be private, as well as use of the final specifier.
The reputation system won't let me leave this as an answer in that question, so I had to provide it as another question...
#include <iostream>
#include <memory>
class Factory final {
public:
template<typename T, typename... A>
static std::shared_ptr<T> make_shared(A&&... args) {
auto ptr = std::make_shared<Type<T>>(std::forward<A>(args)...);
return std::shared_ptr<T>(ptr, &ptr->type);
}
private:
template<typename T>
struct Type final {
template<typename... A>
Type(A&&... args) : type(std::forward<A>(args)...) { std::cout << "Type(...) addr=" << this << "\n"; }
~Type() { std::cout << "~Type()\n"; }
T type;
};
};
class X final {
friend struct Factory::Type<X>; // factory access
private:
X() { std::cout << "X() addr=" << this << "\n"; }
X(int i) { std::cout << "X(...) addr=" << this << " i=" << i << "\n"; }
~X() { std::cout << "~X()\n"; }
};
int main() {
auto ptr1 = Factory::make_shared<X>();
auto ptr2 = Factory::make_shared<X>(42);
}
Giving the following output under gcc...
X() addr=0x62bc30
Type(...) addr=0x62bc30
X(...) addr=0x62bc50 i=42
Type(...) addr=0x62bc50
~Type()
~X()
~Type()
~X()
Just a followup... The approach above doesn't play well with std::enable_shared_from_this<> because the initial std::shared_ptr<> is to the wrapper and not the type itself. We can address this with an equivalent class that is compatible with the factory...
#include <iostream>
#include <memory>
template<typename T>
class EnableShared {
friend class Factory; // member access
public:
std::shared_ptr<T> shared_from_this() { return weak.lock(); }
protected:
EnableShared() = default;
virtual ~EnableShared() = default;
EnableShared<T>& operator=(const EnableShared<T>&) { return *this; } // no slicing
private:
std::weak_ptr<T> weak;
};
class Factory final {
public:
template<typename T, typename... A>
static std::shared_ptr<T> make_shared(A&&... args) {
auto ptr = std::make_shared<Type<T>>(std::forward<A>(args)...);
auto alt = std::shared_ptr<T>(ptr, &ptr->type);
assign(std::is_base_of<EnableShared<T>, T>(), alt);
return alt;
}
private:
template<typename T>
struct Type final {
template<typename... A>
Type(A&&... args) : type(std::forward<A>(args)...) { std::cout << "Type(...) addr=" << this << "\n"; }
~Type() { std::cout << "~Type()\n"; }
T type;
};
template<typename T>
static void assign(std::true_type, const std::shared_ptr<T>& ptr) {
ptr->weak = ptr;
}
template<typename T>
static void assign(std::false_type, const std::shared_ptr<T>&) {}
};
class X final : public EnableShared<X> {
friend struct Factory::Type<X>; // factory access
private:
X() { std::cout << "X() addr=" << this << "\n"; }
X(int i) { std::cout << "X(...) addr=" << this << " i=" << i << "\n"; }
~X() { std::cout << "~X()\n"; }
};
int main() {
auto ptr1 = Factory::make_shared<X>();
auto ptr2 = ptr1->shared_from_this();
std::cout << "ptr1=" << ptr1.get() << "\nptr2=" << ptr2.get() << "\n";
}
I am trying to understand different topics in C++ by examples and I cannot get this example to work:
template<typename T>
class zero_init
{
T val;
public:
zero_init() : val(static_cast<T>(0)) { std::cout << "In constructor with no parameters\n"; }
operator T() const { std::cout << "In operator T()\n"; return val; }
};
int main()
{
const zero_init<int> x;
x(); //Error!
return 0;
}
I am obviously trying to call the operator() but it gives the error: "call of an object of a class type without appropriate operator()"
You accidentally implemented a type conversion operator and not operator(). Overload operator() like this instead (I removed the return value because you discard it in main anyway):
#include <iostream>
template<typename T>
class zero_init
{
T val;
public:
zero_init() : val(static_cast<T>(0)) { std::cout << "In constructor with no parameters\n"; }
void operator()() const { std::cout << "In operator()\n"; }
};
int main()
{
const zero_init<int> x;
x();
return 0;
}
If you actually need the return value, do it like this:
#include <iostream>
template<typename T>
class zero_init
{
T val;
public:
zero_init() : val(static_cast<T>(0)) { std::cout << "In constructor with no parameters\n"; }
T operator()() const { std::cout << "In operator()\n"; return val; }
};
int main()
{
const zero_init<int> x;
auto val = x();
return 0;
}
I recently read simple STL sources,Here is the code:
#include <iostream>
#include <cstddef>
using namespace std;
class alloc
{
};
template <typename T, typename Alloc = alloc, size_t Bufsiz = 0>
class deque
{
public:
deque() { cout << "deque()" << endl; }
};
template <typename T, typename Sequence = deque<T> >
class stack
{
public:
stack() { cout << "stack()" << endl; }
private:
Sequence c;
};
int main()
{
stack<int> x;
return 0;
}
The output:
deque()
stack()
When i created a stack object,it should have called stack constructor first.But the fact is not.
Why the compiler calls deque constructor first?
Before you enter the body of a constructor, base class constructors are called, then all non-static member variables are default initialized in the order of declaration, unless they appear in a member initialization list. In your code Sequence c is initialized first and then the body of Stack::Stack() is executed.
This program illustrates the order of construction - destruction.
#include <iostream>
#include <string>
using namespace std;
struct Base_1
{
Base_1()
{
cout << "Base_1\n";
}
~Base_1()
{
cout << "~Base_1\n";
}
};
struct Base_2
{
Base_2()
{
cout << "Base_2\n";
}
~Base_2()
{
cout << "~Base_2\n";
}
};
struct Member_1
{
Member_1()
{
cout << "Member_1\n";
}
~Member_1()
{
cout << "~Member_1\n";
}
};
struct Member_2
{
Member_2()
{
cout << "Member_2\n";
}
~Member_2()
{
cout << "~Member_2\n";
}
};
struct Member_non_default
{
Member_non_default( string s )
{
cout << "Member non default\n";
}
~Member_non_default()
{
cout << "~Member non default\n";
}
};
struct Static_member
{
Static_member()
{
cout << "Static member\n";
}
~Static_member()
{
cout << "~Static member\n";
}
};
struct Derived: Base_1, Base_2
{
Member_1 m1;
Member_non_default m;
Member_2 m2;
static Static_member sm;
Derived():
m { "Member non default\n" }
{
cout << "Derived\n";
}
~Derived()
{
cout << "~Derived\n";
}
};
Static_member Derived::sm;
int main()
{
Derived d;
}
Output
Static member
Base_1
Base_2
Member_1
Member non default
Member_2
Derived
~Derived
~Member_2
~Member non default
~Member_1
~Base_2
~Base_1
~Static member
I have a such factories, which instantiate objects by passed template class name T:
template<class T>
class Factory0
{
public:
static void *Create(){ return new T(); }
};
template<class T, class Argument1>
class Factory1
{
public:
static void *Create( Argument1 &arg1 ){ return new T( arg1 ); }
};
And i need to do something like such:
map<string[ClassName], &factory] _builder;
...
template<class T>
Add(){
if( T derived from BaseClass ) _builder[T] = &factory1::Create
else if( T derived from BaseClass ) _builder[T] = &factory0::Create;
}
template<class T>
Create() {
return _builder[T]( (factory0) ? <nothing> : <some_argument> );
}
This is hard for two reasons:
Calling create with the wrong arguments can only be caught at runtime, so we need a bit of dynamic typing.
C++ really doesn't like casting function pointers. Or creating pointers to templated functions. Or generally doing anything complex with function pointers.
But it can be done:
#include<string>
#include<map>
#include<iostream>
using namespace std;
struct returnable {
// Put some interesting virtual functions here
};
struct foo : public returnable {
foo() {
cout << "defaulFoo" << endl;
}
foo(int x) {
cout << "Foo:" << x << endl;
}
};
struct bar : public returnable {
bar(char a, char b){
cout << "bar:" << a << "," << b << endl;
}
};
template<typename... ARGS>
struct newmakerbase {
virtual returnable* make(ARGS... args) = 0;
};
template<typename OUT, typename... ARGS>
struct newmaker : public newmakerbase<ARGS...> {
virtual returnable* make(ARGS... args) {
return new OUT(args...);
}
};
// Boost might provide a neater version of this
int nextId = 0;
template<typename... T>
struct typeId {
static const int id;
};
template<typename... T>
const int typeId<T...>::id = nextId++;
map<string,void*> builders;
map<string,int> argtypes;
template<typename OUT, typename... ARGS>
void registerClas(string name) {
builders[name] = static_cast<void*>(new newmaker<OUT,ARGS...>());
argtypes[name] = typeId<ARGS...>::id;
}
template<typename... ARGS>
returnable* create(string name, ARGS... args) {
int argsgiven = typeId<ARGS...>::id;
if (argsgiven != argtypes[name]) {
// TODO: maybe throw an exception or something?
return NULL;
}
newmakerbase<ARGS...>* builder = static_cast<newmakerbase<ARGS...>*>(builders[name]);
return builder->make(args...);
}
main() {
registerClas<foo>("defaultFoo");
registerClas<foo,int>("foo");
registerClas<bar,char,char>("bar");
returnable* a = create("defaultFoo");
returnable* b = create("foo", 42);
returnable* c = create("foo", 'a', 'b'); // returns NULL
returnable* d = create("foo", 42.0); // also returns NULL
returnable* e = create("bar", 'c', 'd');
cout << a << " " << b << " " << c << " " << d << " " << e << endl;
}