|
Thanks for the information.
I'm going to read about that...
SV.
|
|
|
|
|
Adding some food for thought
#include <vector>
class base
{
public:
template<class T>
static void sum(T &dest, const T &src)
{
dest.privateadd(src);
}
template<class T, class U>
static void sum(T &dest, const U &src)
{
}
private:
template<class T>
void privateadd(const T &t)
{
virtualadd(&t);
}
virtual void virtualadd(const base *arg) = 0;
};
template< class T >
class CTest : public base
{
public:
T mem;
private:
virtual void virtualadd(const base *arg)
{
const CTest<T> *other = static_cast<const CTest<T>*>( arg );
mem += other->mem;
}
};
int main()
{
std::vector<base*> all;
CTest<int> a;
CTest<double> b;
base::sum(a, b); base::sum(a, a); base::sum(a, 1); all.push_back(&a); all.push_back(&b); base::sum(*all[0], *all[1]);
base::sum(*all[0], *all[0]);
}
|
|
|
|
|
Pretty cool!
I was wondering how I could get rid of the dynamic_cast but completely missed the idea of using free functions (or statics) to do it.
Cheers,
Ash
|
|
|
|
|
Still, there must be a better way to attack the problem in the first place. The base class get bloated rather quickly when extending it.
I was a bit annoyed though that I couldn't get back to the a.add(b) syntax. One could of course add that method to the CTest<T> class and use it when you don't have to rely on pointers to the base class. But it would have been nice to always be able to use it.
|
|
|
|
|
Thanks everyone for your great comments!!!!!
I just wondering about something based on this code. In fact, I thought of something pretty similar but I didn't even try it since I was thinking that shouldn't work.
When the calls are made :
base::sum(*all[0], *all[1]);
base::sum(*all[0], *all[0]);
I was just thinking that *all[0] and *all[1] will be both of type 'base' than the dest and source of the static function sum will always be the same. Always ending in this function
template< class T >
static void sum(T &dest, const T &src)
{
dest.privateadd(src);
}
and never in this one
template<class T, class U>
static void sum(T &dest, const U &src)
{
}
Ultimately we will enter the virtualadd of class CTest with different type to handle. Then, the static_cast should fail...
Since you both think it will work, I'm just wondering where I'm wrong...
SV.
|
|
|
|
|
Bum, good spot! Hang on, why are you the one asking us questions?
Back to the drawing board...
Ash
|
|
|
|
|
Oh, crap. (I was tempted to say that this new problem could easily be solved with a dynamic_cast, but I will refrain from that )
I will have another look.
|
|
|
|
|
something like this would also work, ít depends on what you are up to...
class base {
public:
virtual void accept(class visitor&) = 0;
};
template<typename T>
class impl : public base {
public:
virtual void accept(class visitor& v);
};
class visitor {
public:
void operator()(base* b) {
b->accept(*this);
}
void visit(impl<int>& pimpl) {
std::cout << "i am an int" << std::endl;
}
void visit(impl<double>& pimpl) {
}
};
template<typename T>
void impl<T>::accept(visitor& v) {
v.visit(*this);
}
void foo() {
std::vector<base*> vec;
vec.push_back(new impl<int>);
vec.push_back(new impl<double>);
visitor v;
std::for_each(vec.begin(), vec.end(), v);
}
modified on Monday, August 30, 2010 1:55 AM
|
|
|
|
|
I was wondering where your post went This looks a lot neater.
The only drawback I can see is that you have to foresee all possible values of T. As you say, it depends on what needs to be solved.
|
|
|
|
|
Yeah, sorry, I am writing this down on my PocketPC so it's bit hard to see what I actually wrote. I removed the old post since I couldn't edit it anymore.
To foresee all values of T is the price for having the automatic dispatching wo. rtti. You could go the acyclic visitor way with one dyna-cast in accept...
|
|
|
|
|
hello guys...can we overload the main()?? It is just a question and i've no intentions to do so??
MY ANSWER:
May be we could do it(i dont know how), but since the main() is the driver of our program so it should be punishable if someone does it
|
|
|
|
|
Nope, you can't overload main(), at least not in standard C++. You might be able to in C (or rather assign some other object to main by tricking the linker) though.
Cheers,
Ash
|
|
|
|
|
overloaded Name wrote: hello guys...can we overload the main()??
Meaning what? Are you wanting to change the name of your program's entry point? Or are you referring to the many faces of main :
void main( void )
int main( void )
void main( int argc )
int main( int argc )
void main( int argc, char *argv[] )
int main( int argc, char *argv[] )
void main( int argc, char *argv[], char *env[] )
int main( int argc, char *argv[], char *env[] )
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
main always should have a return type of int. Even Microsoft compilers know that if you tell them to disable MS extensions to the language.
|
|
|
|
|
Aescleal wrote: main always should have a return type of int.
It all depends on what you're doing. I seldom use anything other than void , and for good reason.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
Well personally I usually use a C++ compiler to compile C++, but your milage may vary.
Just out of interest what do you think happens if you write:
int main()
{
}
What's returned to the OS? Do you think it's anything different to what happens if you write:
void main()
{
}
and compile with /Ze on Microsoft's compilers?
|
|
|
|
|
Aescleal wrote: What's returned to the OS?
What you are failing to realize is that I don't care what's returned to the OS (i.e., the invoker), if anything. To put it another way, if all I'm doing is some proof-of-concept code, having main() return and accept nothing is perfectly valid.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
Sounds like an interesting concept - not using code that's marginally shorter, standard and portable. At least it'll help confuse future generations of programmers.
|
|
|
|
|
I don't agree.
While I see the point of returning a value of the OS, I personally don't like 'default 0-return value' for code intended to return nothing.
Moreover, the implicit 'return 0; ' statement in the following code is confusing too (at least IMHO).
int main()
{
}
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
CPallini wrote: While I see the point of returning a value of the OS, I personally don't like 'default 0-return value' for code intended to return nothing.
The ponit is that, whatever you like it or not, a process invoked by the OS HAVE TO return an int value back to it. That's how all the kernels are designed.
The OS left the space for an int just before the stack space for main() . Just like C does for whatever function call.
If you declare main as void, you simply tell your program to don't care about the stack under it. That -in fact- doesn't mean "return nothing": it just return to the OS a random value.
The OS is not compiled by you and doesn't link statically your main, so it cannot know what the type it has. It assume it is int . If it's not, the return value will be bogus, not nothing.
2 bugs found.
> recompile ...
65534 bugs found.
|
|
|
|
|
I understand that.
However, from my point of view (as developer), sometimes I simply don't care about returning a meaningful value to the OS. I simply need the OS executing the piece of code, no more, no less.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Why is it confusing? It's only been around since 1989 (with the first C standard). If it really offends you do something like:
void my_main( int argc, char **argv )
{
}
and add a standard and portable main to a library:
int main( int argc, char **argv )
{
my_main( argc, argv );
}
boom boom, you've got what you want (effectively a void entry point to your app) and the great Gods of the C++ standard are appeased as well.
And once you start doing that you can go a bit further...
int main( int argc, char **argv )
try
{
std::vector<std::string> args;
std::copy( argv, argv + argc, std::back_inserter( args ) );
my_main( args );
}
catch( std::exception &e )
{
std::cout << "Something went wrong: " << e.what() << std::endl;
}
catch( ... )
{
std::cout << "Something went wrong, no idea what!" << std::endl;
}
You can start kicking all the boiler plate guff you normally have to do in main away from the meat of your app (creating and wiring you application objects up). Anyway, that last bit is a bit of a digression - the point is don't fight the standard, it'll win in the end - do what a good programmer does with a chuffy API and abstract it, hide it or adapt it.
Cheers,
Ash
|
|
|
|
|
Implicit return 0; statement is confusing, no matter if it is around since then (I would prefer the compiler complaining about the missing return statement).
I know my arguments go against the Good Lord of C++ , anyway who cares?
Still, if I want to do a quick test,
void main()
{
}
is my favourite paradigm.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
A main function returning void is invalid in both C and C++, end of story, no matter that you care about what your program returns or not. (In C++, if you don't, just omit the return statement; in C, you can't omit it, just return 0 .) A compiler that allows a main returning void breaks portability to other compilers (GCC, Intel).
This is clearly stated in ISO's C++ specification (section 3.6.1; also answering the original poster's question):An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined.
See also: C++ FAQ Lite [29.3] Should I use void main() or int main()? and Stroustrup: Can I write "void main()"?.
|
|
|
|
|
DrFrankenstein90 wrote: ...no matter that you care about what your program returns or not.
You're right. How silly of me. What could I have possibly been thinking.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|