template <class T> struct greater : binary_function <T, T, bool> {
bool operator() (const T& x, const T& y) const {
return x > y;
}
};
I found this definition of "Function object class for greater-than inequality comparison" in STL library.
Can somebody please explain to me how this code works and compiles?
template <class T> // A template class taking any type T
// This class inherit from std::binary_function
struct greater : binary_function <T, T, bool>
{
// This is a struct (not a class).
// It means members and inheritens is public by default
// This method defines operator() for this class
// you can do: greater<int> op; op(x,y);
bool operator() (const T& x, const T& y) const {
// method is const, this means you can use it
// with a const greater<T> object
return x > y; // use T::operator> const
// if it does not exist, produces a compilation error
}
};
here is the definition of std::binary_function
template <class Arg1, class Arg2, class Result>
struct binary_function {
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
this allows you to access the types defining the binary_function
greater<int> op;
greater<int>::result_type res = op(1,2);
which is equivalent to
std::result_of<greater<int>>::type res = op(1,2);
It's a template class that can be instantiated with one type argument. So you can say greater<int>, greater<my_class>, etc. Each of those instantiations has an operator() that takes two arguments of type const T& and returns the result of comparing them.
greater<int> gi;
if (gi(1, 2)) {
// won't get here
} else {
// will get here
}
I don't know have much you know about template programming and functors.
Let's start with functors :
struct greater {
bool operator()(const int& x, const int& b) const {
return x > y;
}
greater g;
g(2,3); // returns false
g(3,2); // returns true
So functors mock a function you could have as well implemented bool g(int x, int y){return x>y;} and used it the same way.
The nice thing about functors, is that you can also store some data when working on more complexe data structure.
Then there is the template part : you want to write the same functor for any type, you don't care if the type is an int, a float, a complexe object, the code will be the same. That's what the template part is for.
Related
I want to define a class, called Nested here, that will contains two or more (one here) data members that support arithmetic operations using expression templates, for example an std::valarray. For this class itself, I am defining its own expression templates and I want to "forward" the arithmetic operations down to the members.
A minimal (non)working example is given below:
#include <iostream>
#include <valarray>
template <typename E>
struct NestedExpr {
operator const E& () const {
return *static_cast<const E*>(this);
}
};
template <typename A>
class Nested : public NestedExpr <Nested<A>>{
private:
A a;
public:
Nested(const A& _a) : a(_a) {}
template <typename E>
inline Nested<A>& operator = (const NestedExpr<E>& _expr) {
const E& expr(_expr);
a = expr.get_a();
return *this;
}
inline A& get_a() { return a; }
inline const A& get_a() const { return a; }
};
// ================================================================= //
template <typename ARG, typename S>
class NestedMul : public NestedExpr<NestedMul<ARG, S>> {
public:
const ARG& arg;
const S s;
NestedMul(const ARG& _arg, S _s) : arg(_arg), s(_s) {}
inline auto get_a() const { return arg.get_a() * s; };
};
template< typename ARG, typename S>
inline NestedMul<ARG, S> operator * (S s, const NestedExpr<ARG>& arg) {
return {arg, s};
}
// ================================================================= //
template <typename ARG1, typename ARG2>
class NestedAdd : public NestedExpr<NestedAdd<ARG1, ARG2>> {
public:
const ARG1& arg1;
const ARG2& arg2;
NestedAdd(const ARG1& _arg1, const ARG2& _arg2)
: arg1(_arg1), arg2(_arg2) {}
inline auto get_a() const { return arg1.get_a() + arg2.get_a(); };
};
template<typename ARG1, typename ARG2>
inline NestedAdd<ARG1, ARG2>
operator + (const NestedExpr<ARG1>& arg1, const NestedExpr<ARG2>& arg2) {
return {arg1, arg2};
}
int main () {
std::valarray<double> x1 = {4.0};
std::valarray<double> x2 = {3.0};
std::valarray<double> x3 = {0.0};
std::valarray<double> x4 = {0.0};
auto a = Nested<std::valarray<double>>(x1);
auto b = Nested<std::valarray<double>>(x2);
auto c = Nested<std::valarray<double>>(x3);
// this returns 21
c = 2*a + 3*b;
std::cout << c.get_a()[0] << std::endl;
// works as expected, returns 17
x4 = 2*x1 + 3*x2;
std::cout << x4[0] << std::endl;
}
The output of this program is
21
17
i.e. forwarding the expression down to the member does not seem to provide the expected result obtained directly from using the valarrays.
Any help here is appreciated.
In the below function definition:
inline auto get_a() const { return arg.get_a() * s; };
your expected behavior is that auto deduces std::valarray<double>, that is, the result type of a multiplication of std::valarray<double> and int which is a new object that already stores values multiplied by the integer.
This is how operator* is defined [valarray.binary]/p2:
template <class T>
valarray<T> operator*(const valarray<T>&,
const typename valarray<T>::value_type&);
However, there's the following paragraph in the standard [valarray.syn]/p3:
Any function returning a valarray<T> is permitted to return an object of another type, provided all the const member functions of valarray<T> are also applicable to this type. This return type shall not add more than two levels of template nesting over the most deeply nested argument type.
This type must be convertible to std::valarray<double>, but itself, for optimization purposes, may not represent the actual result before that conversion happens.
That is, here's the actual type deduced for auto by GCC:
std::_Expr<std::__detail::_BinClos<std::__multiplies
, std::_ValArray
, std::_Constant, double, double>, double>
and here's what Clang uses:
std::__1::__val_expr<std::__1::_BinaryOp<std::__1::multiplies<double>,
std::__1::valarray<double>, std::__1::__scalar_expr<double> > >
In other words, you are returning by value an object which probably defers the actual computations. In order to do so, those intermediate objects need to store somehow the deferred subexpressions.
Inspecting GCC libstdc++'s implementation, one can find the following representation:
template <class _Oper, class _FirstArg, class _SecondArg>
class _BinBase
{
public:
typedef typename _FirstArg::value_type _Vt;
typedef typename __fun<_Oper, _Vt>::result_type value_type;
_BinBase(const _FirstArg& __e1, const _SecondArg& __e2)
: _M_expr1(__e1), _M_expr2(__e2) {}
// [...]
private:
const _FirstArg& _M_expr1;
const _SecondArg& _M_expr2;
};
Note that subexpressions are stored as references. This means that in the definition of get_a():
return arg1.get_a() + arg2.get_a();
_M_expr1 and _M_expr2 are bound to temporary objects:
arg1.get_a()
arg2.get_a()
i.e., intermediate objects which are the results of multiplications, whose lifetime ends as soon as NextedAdd::get_a() exits, leading to undefined behavior when the result is eventually computed, in particular, when the implementation attempts to access each individual element of that intermediate subexpressions:
value_type operator[](size_t __i) const
{
return _Oper()(_M_expr1[__i], _M_expr2[__i]);
}
A quick solution would be to use the following return type:
std::decay_t<decltype(arg.get_a())> get_a() const { return arg.get_a() * s; }
This will recursively ensure that the final result type of any operation will be whatever the original type T in Nested<T> was, i.e., std::valarray<double>.
DEMO
template <class T> struct greater : binary_function <T,T,bool> {
bool operator() (const T& x, const T& y) const
{return x>y;}
};
template <class T> struct logical_and : binary_function <T,T,bool> {
bool operator() (const T& x, const T& y) const
{return x&&y;}
};
// (i > 5 && i <=10)
countBoost = std::count_if(vecInts.begin(), vecInts.end(),
boost::bind(std::logical_and<bool>(),
^^^^ // ???? Why ????
boost::bind(std::greater<int>(), _1, 5),
boost::bind(std::less_equal<int>(), _1, 10))
);
Based on my understanding, the pass-in type T for std::logical_and<T> is the type of the pass-in parameters of function operator(). Given the above code, it seems that the type of std::greater is bool that is determined by the returned value of operator().
Is that correct?
Thank you
The return type of the operator() function is bool. The type of
std::greater is std::greater. It's a functional object. Thus:
std::greater<int> g;
std::cout << typeof( g ).name() << std::endl;
will return whatever your compiler uses to display the instantiation
type of a class template: "struct std::greater<int>" for VC++, for
example.
The boost binder does a bit more magic than what you might be expecting. When one of the bound arguments is a bind expression itself, it will execute that expression during the call and use the result. In this case, the internal bound expressions are calls to std::less<int> and std::greater<int>, both of which yield a bool, which is then passed to the std::logical_and<bool>.
Please, consider the code below:
template<typename T>
bool function1(T some_var) { return true; }
template <typename T>
bool (*function2())(T) {
return function1<T>;
}
void function3( bool(*input_function)(char) ) {}
If I call
function3(function2<char>());
it is ok. But if I call
function3(function2());
compiler gives the error that it is not able to deduction the argument for template.
Could you, please, advise (give an idea) how to rewrite function1 and/or function2 (may be, fundamentally to rewrite using classes) to make it ok?
* Added *
I am trying to do something simple like lambda expressions in Boost.LambdaLib (may be, I am on a wrong way):
sort(some_vector.begin(), some_vector.end(), _1 < _2)
I did this:
template<typename T>
bool my_func_greater (const T& a, const T& b) {
return a > b;
}
template<typename T>
bool my_func_lesser (const T& a, const T& b) {
return b > a;
}
class my_comparing {
public:
int value;
my_comparing(int value) : value(value) {}
template <typename T>
bool (*operator<(const my_comparing& another) const)(const T&, const T&) {
if (this->value == 1 && another.value == 2) {
return my_func_greater<T>;
} else {
return my_func_greater<T>;
}
}
};
const my_comparing& m_1 = my_comparing(1);
const my_comparing& m_2 = my_comparing(2);
It works:
sort(a, a + 5, m_1.operator< <int>(m_2));
But I want that it doesn't require template argument as in LambdaLib.
Deduction from return type is not possible. So function2 can't be deduced from what return type you expect.
It is however possible to deduce cast operator. So you can replace function2 with a helper structure like: Unfortunately there is no standard syntax for declaring cast operator to function pointer without typedef and type deduction won't work through typedef. Following definition works in some compilers (works in G++ 4.5, does not work in VC++ 9):
struct function2 {
template <typename T>
(*operator bool())(T) {
return function1<T>;
}
};
(see also C++ Conversion operator for converting to function pointer).
The call should than still look the same.
Note: C++11 introduces alternative typedef syntax which can be templated. It would be like:
struct function2 {
template <typename T>
using ftype = bool(*)(T);
template <typename T>
operator ftype<T>() {
return function1<T>;
}
};
but I have neither G++ 4.7 nor VC++ 10 at hand, so I can't test whether it actually works.
Ad Added:
The trick in Boost.Lambda is that it does not return functions, but functors. And functors can be class templates. So you'd have:
template<typename T>
bool function1(T some_var) { return true; }
class function2 {
template <typename T>
bool operator()(T t) {
function1<T>;
}
};
template <typename F>
void function3( F input_function ) { ... input_function(something) ... }
Now you can write:
function3(function2);
and it's going to resolve the template inside function3. All STL takes functors as templates, so that's going to work with all STL.
However if don't want to have function3 as a template, there is still a way. Unlike function pointer, the std::function (C++11 only, use boost::function for older compilers) template can be constructed from any functor (which includes plain function pointers). So given the above, you can write:
void function3(std::function<bool ()(char)> input_function) { ... input_function(something) ... }
and now you can still call:
function3(function2());
The point is that std::function has a template constructor that internally generates a template wrapper and stores a pointer to it's method, which is than callable without further templates.
Compiler don't use context of expression to deduce its template parameters. For compiler, function3(function2()); looks as
auto tmp = function2();
function3(tmp);
And it don't know what function2 template parameter is.
After your edit, I think what you want to do can be done simpler. See the following type:
struct Cmp {
bool const reverse;
Cmp(bool reverse) : reverse(reverse) {}
template <typename T> bool operator()(T a, T b) {
return reverse != (a < b);
}
};
Now, in your operator< you return an untyped Cmp instance depending on the order of your arguments, i.e. m_2 < m_1 would return Cmp(true) and m_1 < m_2 would return Cmp(false).
Since there is a templated operator() in place, the compiler will deduce the right function inside sort, not at your call to sort.
I am not sure if this help you and I am not an expert on this. I have been watching this post since yesterday and I want to participate in this.
The template cannot deduce it's type because the compiler does not know what type you are expecting to return. Following is a simple example which is similar to your function2().
template<typename T>
T foo() {
T t;
return t;
};
call this function
foo(); // no type specified. T cannot be deduced.
Is it possible to move the template declaration to the class level as follows:
template<typename T>
bool my_func_greater (const T& a, const T& b) {
return a > b;
}
template<typename T>
bool my_func_lesser (const T& a, const T& b) {
return b > a;
}
template <typename T>
class my_comparing {
public:
int value;
my_comparing(int value) : value(value) {}
bool (*operator<(const my_comparing& another) const)(const T&, const T&) {
if (this->value == 1 && another.value == 2) {
return my_func_greater<T>;
} else {
return my_func_greater<T>;
}
}
};
and declare m_1 and m_2 as below:
const my_comparing<int>& m_1 = my_comparing<int>(1);
const my_comparing<int>& m_2 = my_comparing<int>(2);
Now you can compare as follows:
if( m_1 < m_2 )
cout << "m_1 is less than m_2" << endl;
else
cout << "m_1 is greater than m_2" << endl;
I know this is simple and everyone knows this. As nobody posted this, I want to give a try.
I have this template function:
template <class P>
double Determinant(const P & a, const P & b, const P & c) {
return (b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y);
}
but I want to avoid forcing the return type to double all the time -- P::x and P::y could be ints too, and I need this function in both situations. Is there a way to specify the type of x and y, something like this?
//doesn't compile; can't deduce template argument for T
template <typename T, class P>
T Determinant(const P & a, const P & b, const P & c) {
return (b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y);
}
edit: My compiler is VC2005
edit2: sorry to forget to mention: Unfortunately I can't modify the implementation of the structs for P; one of the point types I deal with is MFC/ATL's CPoint, which are hard-coded as { long x; long y; }.
Compiler cannot deduce return-type of function template, from function argument. Type deduction is done with function arguments only.
In C++03, you can define typedef in your class as:
struct A //suppose A is going to be type argument to your function template
{
int x, y; //I'm assuming type of x and y is same!
typedef int value_type; //type of x and y!
};
And then you've to re-write your function as:
template <class P>
typename P::value_type Determinant(const P & a, const P & b, const P & c) {
return (b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y);
}
Notice the return-type now, its a dependent type. Its :
typename P::value_type
The keyword typename is required here.
Alright, as you said you can't modify your structs, then you can use traits instead. Here is how this can be done:
template<typename T> struct PTraits;
//Suppose this is your type which you can't modify
struct A //A is going to be type argument to your function template
{
long x, y;
};
//specialization: defining traits for struct A
template<>
struct PTraits<A>
{
typedef long value_type; //since type of A::x and A::y is long!
};
And your function template would look like this:
template <class P>
typename PTraits<P>::value_type Determinant(const P & a, const P & b, const P & c) {
return (b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y);
}
Notice the return-type; its slightly different now:
typename PTraits<P>::value_type
Again, value_type is a dependent name, so the keyword typename is required.
Note that you've to specialize PTraits<> for each type which you pass to the function template, as I did.
I like to use a traits style approach to this:
template<typename T> struct DeterminantReturnInfo {};
template<> struct DeterminantReturnInfo<MyType> { typedef MyOtherType ReturnType; }
template< typename T >
typename DeterminantReturnInfo<T>::ReturnType Determinant( const P & a, const P & B, const P & c)
{
return (b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y);
}
If you want it to default to double then you just add typedef double ReturnType; to the initial template.
If you're using Visual Studio 2010 or GCC 4.5+, you can use the trailing return type form:
template<class P>
auto fun(const P& a) -> decltype(a.x + a.y){
return a.x + a.y;
}
Thanks to decltype we automatically get the right return type. Also, the computation is still only done once in the body, not in the trailing return.
Check your return Type its of type member variable x/y . You might not returning so type T.
I am not sure if title makes sense.
let me explain what I want to do:
I have template constructor, the argument generally must be reference, but can be value in certain cases.
Ultimately, I would like to have something like:
matrix_adapter(typename adaptable<T,A>::type);
where adaptable<T,A>::type can either be value or reference defending on type of A.
I am not able to do so (template instantiation does not happen), and unsure why.
Right now, my solution is to enable/disable constructor using Sfinae:
matrix_adapter(A a, typename adaptable<T,A>::pass_by_value = 0)
however, that requires two constructors which are essentially the same.
Is it possible to do it using one generic constructor?
more code:
template<typename T>
struct adaptable<T, boost::detail::multi_array::const_sub_array<T, 2, const T*> >
{
typedef void* pass_by_value;
typedef boost::detail::multi_array::const_sub_array<T, 2, const T*> type;
static size_t size1(const type &A) { return A.shape()[0]; }
static size_t size2(const type &A) { return A.shape()[1]; }
static const T* data(const type &A) { return A.origin(); }
};
template<typename T, class L = ublas::column_major>
struct matrix_adapter
: ublas::matrix<T, L, ublas::array_adaptor<T> >
{
typedef ublas::array_adaptor<T> array_type;
typedef ublas::matrix<T, L, array_type> base;
matrix_adapter(size_t size1, size_t size2, T *data)
: base(size1, size2, array_type(size1*size2, pointer()))
{
initialize(data);
}
template<class A>
matrix_adapter(A a, typename adaptable<T,A>::pass_by_value = 0)
: base(adaptable<T,A>::size1(a),
adaptable<T,A>::size2(a),
array_type(adaptable<T,A>::size1(a)*
adaptable<T,A>::size2(a),
pointer()))
{
initialize(adaptable<T,A>::data(a));
}
template<class A>
matrix_adapter(A &a)
: base(adaptable<T,A>::size1(a),
adaptable<T,A>::size2(a),
array_type(adaptable<T,A>::size1(a)*
adaptable<T,A>::size2(a),
pointer()))
{
initialize(adaptable<T,A>::data(a));
}
Your constructor is itself a template, but with a signature of matrix_adapter(typename adaptable<T,A>::type) the compiler cannot deduce the type of A from the call.
By using SFINAE you enable the compiler to deduce A from the first constructor argument, and then the second argument prevents one or other from being considered in the overload set.
I don't believe it is possible to eliminate either constructor.