Code
#include <iostream>
template <typename Type>
class MyContainer
{
private:
Type contained;
public:
MyContainer<Type>(Type & a): contained(a) { std::cout << "&\n"; }
MyContainer<Type>(Type a): contained(a) { std::cout << "_\n"; }
};
class Epidemic
{
private:
int criticality;
public:
Epidemic(int c): criticality(c);
};
int main()
{
// using objects //
Epidemic ignorance(10);
MyContainer<Epidemic> testtube(ignorance); // should print "&"; error instead
// using primitive //
double irrationalnumber = 3.1415;
MyContainer<double> blasphemousnumber(irrationalnumber); // should print "&"; error instead
// using literal //
MyContainer<double> digits(123456789.0); // prints "_"
}
Description
MyContainer<Type>(Type & a) is meant for most everything. However, it won't work with literals (e.g. 1.732). That's why I added a MyContainer<Type>(Type a). However, by adding this, I end up with an ambiguity because non-literals can use either constructor.
Question
Is there a way to satisfy all parameters (both literal and non-literal) given to a constructor?
Just change from the value type parameter to a const reference:
template <typename Type>
class MyContainer
{
private:
Type contained;
public:
MyContainer<Type>(Type & a): contained(a) { std::cout << "&\n"; }
MyContainer<Type>(const Type& a): contained(a) { std::cout << "_\n"; }
// ^^^^^ ^
};
Related
In the class base, we need to write a function such that printing an object will print arguments of an object using oops concept.
#include <iostream>
using namespace std;
class base{
int num;
string s;
public:
base(int elem,string p){
cout<<elem<<" "<<p<<endl;
}
// todo:
};
int main() {
base obj(12,"shivam");
// cout<<obj<<endl;
}
Your current idea is not far from working, except you print the constructor arguments to std::cout as soon as an instance of base is created - not when the programmer using the class expresses such a wish. What you need to do is to save the arguments given when constructing a base. You'll then be able to print them on demand.
Example:
#include <iostream>
#include <string>
class base {
public:
base(int n, const std::string& str) : // save the arguments given using
num(n), s(str) // <- the member initializer list
{
// empty constructor body
}
// declare a friend function with special privileges to read private
// member variables and call private functions:
friend std::ostream& operator<<(std::ostream&, const base&);
private:
int num;
std::string s;
};
// define the free (friend) function with access to private base members:
std::ostream& operator<<(std::ostream& os, const base& b) {
// here you format the output as you'd like:
return os << '{' << b.num << ',' << b.s << '}';
}
int main() {
base obj(12,"shivam");
std::cout << obj << '\n';
}
Output:
{12,shivam}
Try this:
int IntS(int y)
{
return y;
}
class base{
public:
base(int enume, std::string str)
{
std::cout << IntS(enume) << '\n';
std::cout << str << '\n;
}
};
int main()
{
base mybase(IntS(5), "five");
return 0;
}
See also, std::map:
How can I print out C++ map values?
Suppose I have a class in C++11 like this:
class Something
{
...
private:
class1* a;
class2* b;
class3* c;
public:
class1* reada() { return a; }
class2* readb() { return b; }
class3* readc() { return c; }
void customFunctionForclass1();
void customFunctionForclass2();
void customFunctionForclass3();
}
}
I'd like to make the read functions templated so that if another programmer adds another member class, the corresponding read function will be template-magic created.
Something like this maybe?
class Something
{
...
private:
templateContainer = {class1*,class2*,class3*}
template<thing in templateContainer>
thing variableOfTypeThing;
public:
template<thing in templateContainer>
<thing> read() {return variableOfTypeThing<thing>;}
void customFunctionForclass1();
void customFunctionForclass2();
void customFunctionForclass3();
}
As you can tell from the example, I'm confused.
Basically, I have a class which acts as a container for guaranteed unique class variables (no class1 A; class1 B)
Some function groups for the class are almost identical some function groups are highly varied. It would be great for future people to only have to modify the different parts of the class and get the rest from the templates.
I thought maybe there would be a way by splitting this class up into lots of classes and stuffing them into an array of void pointers, but that seems unwise.
Suggestions?
I'd like to make the read functions templated so that if another programmer adds another member class, the corresponding read function will be template-magic created.
You could encapsulate the user defined classes in a thin wrapper class with a read() function that returns the contained instance. Adding a user defined class to Something would then be done by inheriting wrapper<user_defined_class>.
Basically, I have a class which acts as a container for guaranteed unique class variables
Inheriting this wrapper prevents you from including the same class twice so it could possibly be a way forward:
#include <iostream>
// the "thing" wrapper
template<typename T>
struct thing {
// forward construction arguments to the contained variable
template<class... Args>
thing(Args&&... args) : variable(std::forward<Args>(args)...) {}
// basic interface, const and non-const. I called it get() instead of read()
T const& get() const { return variable; }
T& get() { return variable; }
private:
T variable;
};
// a troublesome user defined class that is not default constructibe :-(
struct user_defined {
user_defined() = delete; // silly example really, but it's just to demonstrate
user_defined(const std::string& v) : str(v) {}
user_defined& operator=(const std::string& v) {
str = v;
return *this;
}
std::string const& say() const { return str; }
private:
std::string str;
};
std::ostream& operator<<(std::ostream& os, const user_defined& ud) {
return os << ud.say();
}
// ... and the "Something" class that inherits the wrapped types.
class Something : thing<int>,
thing<double>,
thing<user_defined>
{
public:
// add initial values for types that are not default constructible
Something(const std::string& val) : thing<user_defined>(val) {}
Something() : Something("") {} // default ctor
// access via derived class, const and non-const
template<typename T>
T const& get() const {
return thing<T>::get(); // get() from the correct base
}
template<typename T>
T& get() {
return thing<T>::get(); // get() from the correct base
}
};
void print(const Something& s) {
// using the const interface
std::cout << s.get<int>() << "\n";
std::cout << s.get<double>() << "\n";
std::cout << s.get<user_defined>() << "\n";
}
int main() {
Something foo;
// using the non-const interface to set
foo.get<int>() = 10;
foo.get<double>() = 3.14159;
foo.get<user_defined>() = "Hello world";
print(foo);
}
Edit: It doesn't fulfill the index part of your question though. You access it using the type you'd like to get() as a tag. You basically build a very rudimentary tuple I guess.
Code based on #Ted Lyngmo's answer:
#include <iostream>
#include <string>
template<typename T>
struct thing {
// forward construction arguments to the contained variable
template<class... Args>
thing(Args&&... args) : variable(std::forward<Args>(args)...) {}
// basic interface, const and non-const. I called it get() instead of read()
T const& get() const { return variable; }
T& get() { return variable; }
protected:
T variable;
};
template<typename ...Ts>
struct things : thing<Ts>... {
template<class... SubTs>
things(thing<SubTs>&&... ts) : thing<SubTs>(std::move(ts))... {}
// access via derived class, const and non-const
template<typename T>
T const& get() const {
return thing<T>::get(); // get() from the correct base
}
template<typename T>
T& get() {
return thing<T>::get(); // get() from the correct base
}
};
// a troublesome user defined class that is not default constructibe :-(
struct user_defined {
user_defined() = delete; // silly example really, but it's just to demonstrate
user_defined(const std::string& v) : str(v) {}
user_defined& operator=(const std::string& v) {
str = v;
return *this;
}
std::string const& say() const { return str; }
private:
std::string str;
};
struct non_default {
non_default() = delete;
non_default(int) {}
};
std::ostream& operator<<(std::ostream& os, const user_defined& ud) {
return os << ud.say();
}
// ... and the "Something" class that inherits the wrapped types.
class Something : public things<int, double, user_defined, non_default>
{
public:
// add initial values for types that are not default constructible
Something(const std::string& val) : things(thing<user_defined>(val), thing<non_default>(0)) {}
Something() : Something("") {} // default ctor
};
void print(const Something& s) {
// using the const interface
std::cout << s.get<int>() << "\n";
std::cout << s.get<double>() << "\n";
std::cout << s.get<user_defined>() << "\n";
}
int main() {
Something foo;
// using the non-const interface to set
foo.get<int>() = 10;
foo.get<double>() = 3.14159;
foo.get<user_defined>() = "Hello world";
print(foo);
}
Consider this pseudo-snippet:
class SomeClass
{
public:
SomeClass()
{
if(true)
{
fooCall = [](auto a){ cout << a.sayHello(); };
}
else
{
fooCall = [](auto b){ cout << b.sayHello(); };
}
}
private:
template<typename T>
std::function<void(T)> fooCall;
};
What I want is a class member fooCall which stores a generic lambda, which in turn is assigned in the constructor.
The compiler complains that fooCall cannot be a templated data member.
Is there any simple solution on how i can store generic lambdas in a class?
There is no way you'll be able to choose between two generic lambdas at run-time, as you don't have a concrete signature to type-erase.
If you can make the decision at compile-time, you can templatize the class itself:
template <typename F>
class SomeClass
{
private:
F fooCall;
public:
SomeClass(F&& f) : fooCall{std::move(f)} { }
};
You can then create an helper function to deduce F:
auto makeSomeClassImpl(std::true_type)
{
auto l = [](auto a){ cout << a.sayHello(); };
return SomeClass<decltype(l)>{std::move(l)};
}
auto makeSomeClassImpl(std::false_type)
{
auto l = [](auto b){ cout << b.sayHello(); };
return SomeClass<decltype(l)>{std::move(l)};
}
template <bool B>
auto makeSomeClass()
{
return makeSomeClassImpl(std::bool_constant<B>{});
}
I was not able to store std::function<> as a generic lambda in the class directly as a member. What I was able to do was to specifically use one within the class's constructor. I'm not 100% sure if this is what the OP was trying to achieve but this is what I was able to compile, build & run with what I'm suspecting the OP was aiming for by the code they provided.
template<class>
class test {
public: // While testing I changed this to public access...
// Could not get object below to compile, build & run
/*template<class U = T>
static std::function<void(U)> fooCall;*/
public:
test();
};
template<class T>
test<T>::test() {
// This would not compile, build & run
// fooCall<T> = []( T t ) { std::cout << t.sayHello(); };
// Removed the variable within the class as a member and moved it here
// to local scope of the class's constructor
std::function<void(T)> fooCall = []( auto a ) { std::cout << a.sayHello(); };
T t; // created an instance of <Type T>
fooCall(t); // passed t into fooCall's constructor to invoke the call.
}
struct A {
std::string sayHello() { return "A say's Hello!\n"; }
};
struct B {
std::string sayHello() { return "B say's Hello!\n"; }
};
int main() {
// could not instantiate an object of SomeClass<T> with a member of
// a std::function<> type that is stored by a type of a generic lambda.
/*SomeClass<A> someA;
SomeClass<B> someB;
someA.foo();
someB.foo();*/
// Simply just used the object's constructors to invoke the locally stored lambda within the class's constructor.
test<A> a;
test<B> b;
std::cout << "\nPress any key & enter to quit." << std::endl;
char c;
std::cin >> c;
return 0;
}
With the appropriate headers the above as is should compile, build & run giving the output below (At least in MSVS 2017 on Windows 7 64bit did); I left comments where I ran into errors and tried multiple different techniques to achieve a working example, errors occurred as others suggested and I found even more while working with the above code. What I was able to compile, build and run came down to this simple bit of code here without the comments. I also added another simple class to show it will work with any type:
template<class>
class test {
public:
test();
};
template<class T>
test<T>::test() {
std::function<void( T )> fooCall = []( auto a ) { std::cout << a.sayHello(); };
T t;
fooCall( t );
}
struct A {
std::string sayHello() { return "A say's Hello!\n"; }
};
struct B {
std::string sayHello() { return "B say's Hello!\n"; }
};
struct C {
int sayHello() { return 100; }
};
int main() {
test<A> testA;
test<B> testB;
test<C> testC;
std::cout << "\nPress any key & enter to quit." << std::endl;
char c;
std::cin >> c;
return 0;
}
Output:
A say's Hello!
B say's Hello!
100
Press any key & enter to quit
I don't know if this will help the OP directly or indirectly or not but if it does or even if it doesn't it is still something that they may come back to and build off of.
you can simply use a template class or...
If you can get away with using c++17, you could make fooCall's type std::function<void(const std::any&)> and make a small wrapper for executing it.
method 1 : simply use a template class (C++14).
method 2 : seems to mimic the pseudo code exactly as the OP intended (C++17).
method 3 : is a bit simpler and easier to use than method 2 (C++17).
method 4 : allows us to change the value of fooCall (C++17).
required headers and test structures for the demo :
#include <any> //not required for method 1
#include <string>
#include <utility>
#include <iostream>
#include <functional>
struct typeA {
constexpr const char * sayHello() const { return "Hello from A\n"; }
};
struct typeB {
const std::string sayHello() const { return std::string(std::move("Hello from B\n")); }
};
method 1 :
template <typename T>
class C {
const std::function<void(const T&)> fooCall;
public:
C(): fooCall(std::move([](const T &a) { std::cout << a.sayHello(); })){}
void execFooCall(const T &arg) {
fooCall(arg);
}
};
int main (void) {
typeA A;
typeB B;
C<typeA> c1;
C<typeB> c2;
c1.execFooCall(A);
c2.execFooCall(B);
return 0;
}
method 2 :
bool is_true = true;
class C {
std::function<void(const std::any&)> fooCall;
public:
C() {
if (is_true)
fooCall = [](const std::any &a) { std::cout << std::any_cast<typeA>(a).sayHello(); };
else
fooCall = [](const std::any &a) { std::cout << std::any_cast<typeB>(a).sayHello(); };
}
template <typename T>
void execFooCall(const T &arg) {
fooCall(std::make_any<const T&>(arg));
}
};
int main (void) {
typeA A;
typeB B;
C c1;
is_true = false;
C c2;
c1.execFooCall(A);
c2.execFooCall(B);
return 0;
}
method 3 :
/*Note that this very closely resembles method 1. However, we're going to
build off of this method for method 4 using std::any*/
template <typename T>
class C {
const std::function<void(const std::any&)> fooCall;
public:
C() : fooCall(std::move([](const std::any &a) { std::cout << std::any_cast<T>(a).sayHello(); })) {}
void execFooCall(const T &arg) {
fooCall(std::make_any<const T&>(arg));
}
};
int main (void) {
typeA A;
typeB B;
C<typeA> c1;
C<typeB> c2;
c1.execFooCall(A);
c2.execFooCall(B);
return 0;
}
method 4 :
/*by setting fooCall outside of the constructor we can make C a regular class
instead of a templated one, this also complies with the rule of zero.
Now, we can change the value of fooCall whenever we want.
This will also allow us to do things like create a container that stores
a vector or map of functions that each take different parameter types*/
class C {
std::function<void(const std::any&)> fooCall; //could easily be replaced by a vector or map
public:
/*could easily adapt this to take a function as a parameter so we can change
the entire body of the function*/
template<typename T>
void setFooCall() {
fooCall = [](const std::any &a) { std::cout << std::any_cast<T>(a).sayHello(); };
}
template <typename T>
void execFooCall(const T &arg) {
fooCall(std::make_any<const T&>(arg));
}
};
int main (void) {
typeA A;
typeB B;
C c;
c.setFooCall<typeA>;
c.execFooCall(A);
c.setFooCall<typeB>;
c.execFooCall(B);
return 0;
}
Output from Any method
Hello from A
Hello from B
With a normal class. For example:
class A {
public:
int a;
std::string b;
A() {}
~A() {}
}
We can do:
A x;
x.a = 1;
x.b = "hello";
But now I don't want to do like above. I want to access n_index-th attribute of object. For example pseudo like x.get<2>() (or x.set<2>(...)) like x.b.
How can do that? Have any template for that.
Beside if I want code like that
int number = 2;
x.get<number>()
Any problem with constexpr?
I think the closest you can get is using boost::fusion.
An example would be
#include <boost/fusion/adapted.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/mpl/int.hpp>
#include <iostream>
class A {
public:
int a;
std::string b;
A() {}
~A() {}
};
BOOST_FUSION_ADAPT_STRUCT(A,
(int, a)
(std::string, b)
)
using namespace boost::fusion;
int main()
{
A x;
x.a = 1;
x.b = "hello";
std::cout << at<boost::mpl::int_<0>>(x) << '\n';
std::cout << at<boost::mpl::int_<1>>(x) << '\n';
at<boost::mpl::int_<0>>(x) = 5;
at<boost::mpl::int_<1>>(x) = std::string("World");
std::cout << at<boost::mpl::int_<0>>(x) << '\n';
std::cout << at<boost::mpl::int_<1>>(x) << '\n';
}
If you want to set several values at the same time when you create the object, you could use a multi-parameter constructor. For example, let's imagine you have this:
class A {
public:
int a;
std::string b;
A() {}
~A() {}
};
You could add a constructor that sets a and b:
class A {
public:
int a;
std::string b;
A() {}
A(int a, std::string b) {
this->a = a;
this->b = b;
}
~A() {}
};
That way, you can create your object and set a and b with :
A a = A(1, "hello");
There is no ready-made way of setting the n-th attribute of your object. You could make one, but I would very, very highly recommend that you don't. Like I said above, if you reorder your attributes, then you will have to rework everything.
If you really, really want to make your life very, very, very much harder, a very ugly and error-prone way of doing this would be like :
template<class T>
void A::setNth(int nth, const T& value) {
switch (nth) {
case 1: a = value; break;
case 2: b = value; break;
// You should #include <stdexcept> to use runtime_error, or you could handle the exception in some other way.
default: throw std::runtime_error("A::setNthAttribute : Value of nth is out of bounds.");
}
}
For the getter:
template<class T>
void A::getNth(int nth, T& valueOut) {
switch (nth) {
case 1: valueOut = a; break;
case 2: valueOut = b; break;
default: throw std::runtime_error("A::getNthAttribute : Value of nth is out of bounds.");
}
}
You would use these methods like this:
A a;
a.setNth(1, 2); // put 2 into a
int i;
a.getNth(1, i); // put a into i
Just writing this code send shivers down my spine. Please, never write what I just wrote. Chuck Norris will kill yoU agfh
86sd asdsa dDASD8!4.
What you are considering is in fact possible, but a bit of a headache. I would approach it by creating a template getter and setter for every member that one can set or get, and then having a template method that takes an int and sets or gets the appropriate property. The getters/setters would have to be specialized for the correct type, and throw an error for other types. This method would have to use a switch to return the right member:
class bar {
private:
int a;
std::string b;
template<T>
T getA() {
// error
}
template<T>
T getB() {
// error
}
template<T>
void setA(const T& A) {
// error
}
template<T>
void setB(const T& B) {
// error
}
template <> std::string getB(); // specialization
template <> int getA();
template <> void setB(const std::string&);
template <> void setA(int);
public:
template<T>
T get(int what) {
switch(what) {
case 1:
return getA();
case 2:
return getB();
default:
// handle error here
break;
}
}
template<T>
void set(int what, const T& t) {
switch(what) {
case 1:
return setA<T>(t);
case 2:
return setB<T>(t);
default:
// handle error here
break;
}
}
};
bar b;
b.set<std::string>(2, "foo");
auto str = b.get<std::string>(2);
Here's an elaborate way to accomplish what you want.
#include <iostream>
#include <string>
// A namespace explicitly defined for class A.
namespace A_NS
{
// A template for members of A.
template <int> struct Member;
// Specialization for the first member.
template <> struct Member<1>
{
using type = int;
type var;
};
// Specialization for the second member.
template <> struct Member<2>
{
using type = std::string;
type var;
};
}
class A {
public:
A() {}
~A() {}
template <int N> typename A_NS::Member<N>::type get() const
{
return static_cast<A_NS::Member<N> const&>(members).var;
}
template <int N> void set(typename A_NS::Member<N>::type const& in)
{
static_cast<A_NS::Member<N>&>(members).var = in;
}
private:
// Define a type for the member variables.
struct Members : A_NS::Member<1>, A_NS::Member<2> {};
// The member variables.
Members members;
};
int main()
{
A a;
a.set<1>(10);
a.set<2>("test");
std::cout << a.get<1>() << ", " << a.get<2>() << std::endl;
}
Output:
10, test
I am trying to write a C++ program which wraps numeric values, I am doing this by writing a super class which will handle two simple functions, and an operator overloading function. This is the code I have so far:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
template <class T>
class Number {
protected:
T number;
public:
Number(T num) {
number = num;
}
string mytype() {
return typeid(number).name();
}
string what_am_i() {
ostringstream oss;
oss << "I am " << Number<T>::mytype() << " and my value is " << number;
return oss.str();
}
Number operator+ (Number an) {
Number brandNew = NULL;
brandNew.number = number + an.number;
return brandNew;
}
};
class MyInt : public Number<int> {
public:
MyInt() : Number<int>(0) {};
MyInt(int num) : Number<int>(num) {}
MyInt(const Number<int> &x) : Number<int>(x) {}
};
class MyFloat : public Number<float> {
public:
MyFloat() : Number<float>(0){};
MyFloat(float num) : Number(num){}
MyFloat(const Number<float> &x) : Number<float>(x) {}
};
class MyDouble : public Number<double> {
public:
MyDouble() : Number<double>(0){};
MyDouble(double num) : Number(num){}
MyDouble(const Number<double> &x) : Number<double>(x) {}
};
In the main function I would like to do something like :
void main() {
MyInt two = 2;
MyFloat flo = 5.0f;
MyDouble md3 = flo + two;
}
And wish for md3 to be 15.00000, up to now an addition of two objects from the same type works great but when I am trying to add a MyInt and MyFloat the compiler doesn't like it. Does anyone have an idea how could I implement this?
You have to add the type operator for your template class:
operator T()
{
return number;
}
This is the complate code that I tested and work:
template <class T>
class Number {
protected:
T number;
public:
Number(T num) {
number = num;
}
string mytype() {
return typeid(number).name();
}
string what_am_i() {
ostringstream oss;
oss << "I am " << Number<T>::mytype() << " and my value is " << number;
return oss.str();
}
Number operator+ (Number an) {
Number brandNew = NULL;
brandNew.number = number + an.number;
return brandNew;
}
operator T()
{
return number;
}
};
I try to explain better why it works. When you make overloading of the plus operator, you want to do something like: left_value + right_value, where right_value is the "an" argument of the plus operator.
Now to get the right value of your object "an", you have to overloading the "type operator", if you don't make overloading of this operator inside your Number class it can not be read as a right value. The following example is for the operator=(), but is valid also for operator+():
template<typename T>
class Number
{
T value;
public:
T operator=(T arg) // Assignment, your class is seen as left operand
{
value = arg;
}
operator T() // Getting, your class is seen as right operand
{
return value;
}
}
Number<int> A; // define a new class Number as int
Number<double> B; // define a new class Number as double
A = B; // is same to A.operator=( B.double() );
to assign A as left value is called the operator "operator=()" of the class Number, while to get B as right value is called the "operator T()" of the class Number
Now this is translated as:
// instance of the operator = of the class Number<int>
int operator=(int arg)
{
}
// instance of the Operator T of the class Number<double>
operator double()
{
}
this traslation emulates the follwoing semantic for A and B object:
int A;
double B;
A = B;
Ciao
Angelo
You may specify the result of a binary operation and use a freestanding operator:
#include <iostream>
#include <typeinfo>
template <class T>
class Number {
template <typename>
friend class Number;
protected:
T number;
public:
Number(const T& num)
: number(num)
{}
template <typename U>
Number(const Number<U>& num)
: number(num.number)
{}
// ...
const T& value() const { return number; }
};
typedef Number<int> MyInt;
typedef Number<float> MyFloat;
typedef Number<double> MyDouble;
template <typename A, typename B>
struct NumberResult;
template <typename X>
struct NumberResult<X, X> {
typedef X type;
};
template <> struct NumberResult<int, float> { typedef float type; };
template <> struct NumberResult<float, int> { typedef float type; };
// ...
template <typename A, typename B>
inline Number<typename NumberResult<A, B>::type>
operator + (const Number<A>& a, const Number<B>& b) {
return Number<typename NumberResult<A, B>::type>(a.value() + b.value());
}
Note: Please avoid using namespace std; in a header.