Overloading operator T***() - c++

I don't know, why my code doesn't work. I create struct and inside put overloading operatoroperator T***(), In main I'd like using following notation const int * const * const * p1 = a;
struct A{
template<class T> operator T***(){}
};
int main(){
A a;
const int * const * const * p1 = a;
return 0;
}
Error: undefined reference to '_ZN1AcvPPPT_IKiEEv'

You simply missed to give your type conversion function an implementation
struct A{
template<class T> operator T***() {
return nullptr; // Do whatever you want to do here.
}
};
See a working sample please.

I have absolutely no idea what you are trying to do, but your problem is a linker problem. You just declare (but not define) the conversion operator T***. You have to define it,
template<class T> operator T***()
{
// define it here
}

Before you edited the question:
template<class T> operator T***();
declares the operator template, but doesn't define it, hence the error that it's undefined. You'll get that error even if you define the template in another source file, since templates must be defined in every translation unit that uses them.
After the edit:
template<class T> operator T***(){}
the code compiles, but has undefined behaviour since the operator is missing a return statement.

Related

C++ safe bool wrapper

I'm trying to design a bool wrapper struct applying the safe bool idiom.
The classic implementation to solve this is pretty trivial: the skeleton could be something like this:
struct Bool final
{
Bool() = default;
Bool(bool value)
: _value{value}
{}
explicit operator bool() const {
return _value;
}
private:
bool _value{false};
};
The part I'm trying to improve is how Bool is constructed.
For example I want to avoid implicit narrowing by design:
Bool b1(45); // yields warnings, but it compiles
Bool b2{3}; // not ok by standard
I tried to hurt myself using templates, but without success.
How could I make it work?
You can achieve this by explicitly deleting all other constructors.
struct Bool final
{
template<class T>
Bool(T) = delete;
Bool(bool value);
};
Add, and explicitly delete a template constructor:
template <typename T>
Bool(T) = delete;
It matches anything other than actual bool better than other constructors, and will thus prevent implicit conversion.
If you just need:
A variable that is only "true" or "false" and cannot be implicitly converted to int/char/pointer then I would look at using an enum class:
enum class Bool {
False,
True,
};
I'm trying to design a bool wrapper struct applying the safe bool idiom.
Don't.
The safe bool idiom is only relevant in C++03 and earlier - where if you express that your type is "truthy" by doing something like:
struct A {
operator bool() const;
};
you'd run into all sorts of issues like:
A{} + 4; // ok?!
A{} < 0; // ok?!
A{} == B{}; // ok if B also has operator bool??!
So the safe bool idiom was a solution to this accidental implicit conversion problem, using function pointers (of course, function pointers!).
In C++11, we have a way better solution:
struct A {
explicit operator bool() const;
};
which does exactly what we want. In fact, it was literally designed to solve this problem. And while the safe bool idiom is fairly complicated scaffolding, explicit operator bool is super straightforward to use and just does the Right Thing. You don't need a wrapper for it - it's actually harder to use your wrapper than to write the explicit operator bool directly.
Moreover, your wrapper imposes on the user (a) non-derivability because you made Bool final and (b) an extra bool member, that you have to keep in sync, so it introduces rather than solves problems. Consider how much more work it would be for you to implement:
template <class T>
struct my_unique_ptr : Bool { ... };
vs
template <class T>
struct my_unique_ptr {
T* ptr;
explicit operator bool() const { return ptr; }
};

Call of explicitly instantiated template function through conversion operator

Let us assume we have a function template which is implemented in the cpp file with help of explicit instantiation like this:
function.h
template<typename T> void function(T val);
function.cpp
#include "function.h"
template<typename T> void function(T val) { /* do something */ }
template void function<double>(double val);
We are now able to call the function in a main file that includes function.h like this:
double val = 1.0;
function(val);
Let us further assume we have a class which is implemented like this:
data.h
class Data
{
private:
double mVal;
public:
Data(double val) { mVal = val; }
operator double () { return mVal; }
};
The following code results in the linker error LNK2019: unresolved external (Visual Studio 2010):
Data a(1.0);
function(a);
We could use one of the following expressions to supply a to function()
function<double>(a);
function(double(a));
...
but why is it not possible to just call function(a)? Does there exist any other solution to achieve that without explicitly instantiating function() with type Data?
why is it not possible to just call function(a)?
It is. You're calling it. But remember that function is declared as:
template<typename T> void function(T val);
so template deduction will deduce function<Data>. The template deduction doesn't know that elsewhere in the code you only have a definition for function<double> - it just does deduction. And function<Data> doesn't have a definition, so it fails to link.
Performing the explicit cast yourself (either function<double>(a) or function(static_cast<double>(a))) would be the best solution in my opinion. Explicit is nice. You could additionally write a separate function with all the overloads you actually support and just forward to the function template:
void fwd_function(double v) { function(v); }
void fwd_function(foo v) { function(v); }
void fwd_function(bar v) { function(v); }
fwd_function(a); // now we call function<double> because fwd_function(double )
// is the what we're actually calling
It is not possible to call function(a), because then T will be of type Data, and not double, even though it has that conversion operator. And because you are not explicitly defining it in the cpp file, you get a linker error.
Here are some solutions you could use:
//Call operator double() explicitly
function(a.operator double());
//Specify T
function<double>(a);
//Casting
function(static_cast<double>(a));

Compilation error about operator reloading using boost::variant

I'am trying to learn boost.variant. However, the code which I copied from a book won't pass the compilation:
class var_print : public boost::static_visitor<void>
{
public:
template<typename T>
void operator()(T &i) {
i *= 2;
cout<<i<<endl;
}
};
Here is how I tried to use it.
typedef boost::variant<int,double,string> var_t;
var_t v(1); //v->int
boost::apply_visitor(var_print(),v);
The compiler generates the following error:
ERROR:no match for 'operator*=' in 'i *= 2'
That puzzles me,since template function will determine the type of parameter whenever it's called and int should defined the operator *=.
You need to have a separate operator() for std::string& since no operator *= is defined for std::string.
In addition, your operator must be marked const since you are passing a temporar visitor instance to apply_visitor.

Unable match function definition to an existing definition in templated class

I'm sorry if such a question is asked before but i could not find no matter how much I searched (there were similar questions but none of them seemed to work for me).
I am writing a templated class and everything works fine except when I try to overload operator+. I try to overload operator+ two times for different parameters but compiler does not see one of the definitions and gives an eror. Here's the code:
Worker.h (one of my previos homeworks, implemented the problem here since it is easier to see ):
#ifndef _WORKER_H
#define _WORKER_H
#include <string>
#include "Project.h"
using namespace std;
template <class T>
class Worker {
public:
Worker(const string &, Project &);
void Work(const int &);
const Worker & Worker::operator+(const int &); //Problem
const Worker & Worker::operator+(const string &); //Problem
string getName() const;
int getTime() const;
private:
string myName; //The name of the worker
Project & myProject;
int myTime; //Variable to keep track of how much the worker worked.
};
#include "Worker.cpp"
#endif
and the relevant part of Worker.cpp:
template <class T>
const Worker<T> & Worker<T>::operator+(const int & add)
{
cout << add;
return *this;
}
template <class T>
const Worker<T> & Worker<T>::operator+(const string & add)
{
cout << add;
return *this;
}
+ operators are not doing anything right now, the problem is the compiler only sees first declared function (in this case the with the parameter int). There also does not seem to be problem with the functions because if I try to overload only one time, both of them work fine alone. Also I can use them (making the necessary changes) in a non-templated class.
I think it is something simple but since I'm new to templates I could not figure out what the problem was.
There are a few problems with your approach, unrelated to templates.
First your operators would only work for one ordering of operations: Worker<T> + int, and not int + Worker<T>
Second typically you would want to return a new Worker instance, not return this by reference, because A+Bshould not modify A or B.
So what you could do is define non-member operators for the different orderings:
template <typename T>
Worker<T> operator+(int i, const Worker<T>& t) { }
template <typename T>
Worker<T> operator+(const Worker<T>& t, int i) { }
and so on.
Note that for operators that should affect the state of the object, such as +=, *= and so on, the usual approach is to use member operators and return by reference, because in these cases it makes perfect sense.
2 things here, 1 of which is your issue
The return type of a member function is not affected by the fact that the class is a template, hence the declaration of operator+ returning Worker and the definition returning Worker<T> are different. In the class definition, they should be:
const Worker<T> & operator+(const int &); //Problem
const Worker<T> & operator+(const string &); //Problem
The other thing which is also changed in the above code is you don't need the scope (Worker::) in a class declaration

type casting problem with template class in C++

I am not a template or type casting expert, so I really need some help.
I have to use an existing template class and encounter the following type cast problem.
I put some sample code to illustrtrate the problem.
//template class definition
template <class IntType>
class CUSTOMIZE_Int: public CUSTOMIZE_Type
{
public:
operator const IntType() const;
private:
IntType m_int;
}
template<class IntType>
CUSTOMIZE_Int<IntType>::operator const IntType() const
{
return m_int;
}
// the template class instantiation
typedef CUSTOMIZE_Int<WRAPPER_Int32> CUSTOMIZE_UnsignedInt;
Then in my code, I derive a new class
// the derived class definition
class IntNum: public CUSTOMIZE_UnsignedInt
{
// ctors and new methods;
}
and creat a variable, and try to make the conversion to get the data.
class IntNum& i;
const WRAPPER_Int32 j = i;
with the following compile error:
error: cannot convert "IntNum" to "const WRAPPER_Int32" in initialization.
What is the right way to do the conversion, or what is the problem with my code?
Thanks for any comments!
I guess that you expect operator IntType()
class ...
operator const IntType() const;
}
to act here, when you assign i to j:
const WRAPPER_Int32 j = i;
However, this is not an implicit conversion, you must do it explicitely:
const WRAPPER_Int32 j = (WRAPPER_Int32) i;
Hope this helps.