Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
78 views
in Technique[技术] by (71.8m points)

c++ - How to pass numeric operator as a parameter?

In C++, we can do something like the following,

template <class OP>
int f(OP op){
   return op(1,2);
}

int main(){
    int res1 = f(std::plus<int>{});
    int res2 = f(std::multiplies<int>{});
}

How could I do the same thing with simple numeric operator,

int main(){
    int res1 = f(+);
    int res2 = f(*);
}

Exactly, what I want to know is how to write the line of 'return' in function f.

question from:https://stackoverflow.com/questions/65623001/how-to-pass-numeric-operator-as-a-parameter

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

How could I do the same thing with simple numeric operator,

You cannot; not using a function template. Operators are not something that can be passed as arguments or stored in objects.

what I want to know is how to write the line of 'return' in function f.

There is no way you can write f as a function template that would make f(+) work because f(+) would be syntactically ill-formed.

As shown in a comment, that can be done using a macro:

#define MY_MACRO_WITH_UNIQUE_NAME(op) 
[]{                                   
    return 1 op 2;                    
}()

int res1 = MY_MACRO_WITH_UNIQUE_NAME(+);
int res2 = MY_MACRO_WITH_UNIQUE_NAME(*);

#undef MY_MACRO_WITH_UNIQUE_NAME

Note that macros are prone to name collisions, so make sure that the name you pick isn't used nor is likely to be used by others.

There's no reason to do this rather than just using the template and std::plus that you wrote initially. Macros are useful though for defining a set of identical operator overloads for example, because in that case you cannot avoid using the operator symbol. Here is something that I've written:

#define FOO_DEFINE_OP(op, trait)                                     
    template <class T, class = std::enable_if_t<trait<T>::value> >   
    constexpr bool operator op(const foo<T>& lhs, const foo<T>& rhs) 
    {                                                                
        return lhs.t op rhs.t;                                       
    }

FOO_DEFINE_OP(==, boost::has_equal_to)
FOO_DEFINE_OP(!=, boost::has_not_equal_to)
FOO_DEFINE_OP(<,  boost::has_less)
FOO_DEFINE_OP(<=, boost::has_less_equal)
FOO_DEFINE_OP(>,  boost::has_greater)
FOO_DEFINE_OP(>=, boost::has_greater_equal)

#undef FOO_DEFINE_OP

This should hopefully become less needed with the introduction of defaulted comparison operators in C++20.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...