Re: Constructor syntax woes.
* willo@cynd.net:
Below is a condensed version of some code I'm having difficulty with:
===============================================================
#include <cstddef> // size_t
Well, with the current standard formally this only gives you std::size_t, but
all or nearly all compilers also place it in the global namespace. With C++0x
it's allowed to also give you size_t in global namespace. Because of that it's
now, IMHO, misleading to use the <c...> headers; just use <stddef.h>.
#include <functional> // binary_function
// the input parameter type to a class constructor.
template< typename T >
struct ABinaryFunction : public std::binary_function< T, size_t,
double >
{
typename ABinaryFunction::result_type
operator()( typename ABinaryFunction< T >::first_argument_type lhs,
typename ABinaryFunction< T >::second_argument_type
rhs )
{
return ABinaryFunction< T >::result_type();
}
};
OK, except you'll probably want to add a 'const' for the operator() (presumably
it's not changing the functor object, but just computing something).
template< typename T >
class AClass
{
public:
// constructor takes one specialized binary_function type parameter.
AClass( std::binary_function< T, size_t, double > function )
{
}
If you want to somehow retain the functor object then you need to use some other
kind of argument, possibly a templated constructor. As it is your actual
argument will be sliced to std::binary_function. Not much you can do with a pure
std::binary_function!
// arbitrary method to test instantiation.
bool True()
{
return true;
}
};
int main()
{
// this won't create a class of type "AClass".
AClass< int > instance_a( ABinaryFunction< int >() );
This is an example of what's been called "the most vexing parse" in C++. The
rule is that if the compiler can treat a declaration as a function declaration,
it will. And here it can, so it does.
You can fiddle with extra parentheses and the like, to convince the compiler
that that argument can't possibly be a type, but that yields unclear code.
So instead just do
ABinaryFunction<int> foo;
AClass<int> instance_a( foo );
Or you can introduce a factory function for your binary functors,
template< typename T >
ABinaryFunction<T> aBinaryFunction() { return ABinaryFunction<T>(); }
and then in main you can declare
AClass<int> instance_a( aBinaryFunction<int>() );
Anyway, as noted earlier, this actual argument will be sliced.
// this will not compile.
bool bool_a = instance_a.True();
// this will create a class of type "AClass", along with an unwanted
binary_function_b.
ABinaryFunction< int > binary_function_b;
AClass< int > instance_b( binary_function_b );
// this will compile.
bool bool_b = instance_b.True();
Yes, that's OK.
return 0;
}
Cheers, & hth.,
- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?