在C ++中为特定函数定义宏

时间:2016-06-10 19:30:25

标签: c++ macros

我想知道是否可以使用宏或内联函数在C ++中进行操作。

(1) postfix operations in normal types (int, char, etc)

int n = 5;
printf("%d\n", n!)

output: 120
(2) infix operations in normal types (int, char, etc)

int a = 20, b = 10
if(b|a) printf("%d is divisor of %d\n", b, a);
// the symbol | means "divides", this is like (a % b == 0)
output: 10 is divisor of 20
(3) sequential operations in common types

int a = 5, b = 15, c = 20;
if(a < b < c) printf("true\n");
output: false
//doesn't matter if it's made with symbols or words
(4) for each (not using for(auto...) C++11) and 
it may different for lists, vectors, etc...

vector<int> v = {1,3,5,7};
foreach(e : v) printf("%d ", e);
output: 1 3 5 7 

那就是它。是否可以在C ++中制作这些宏?

谢谢!

PS:符号不需要|要么 !。因为它们可以工作,所以它们可以是@或$或任何东西。这个想法是后缀(一个@),中缀(一个@ b),顺序(一个@ b @ c),而foreach可能会有所不同,只是要小于正常情况,这是好的

2 个答案:

答案 0 :(得分:1)

  1. 不,您可以创建类似int factorial(int x)的函数并使用printf( .. factorial(...,但不能从宏创建这样的运算符。
  2. 不,|已经是运算符(按位或)。
  3. 无论如何都是这样的。那你想做什么?
  4. 为什么?只需使用汽车?
  5. 我认为你正面临X Y problem.可能没有理由做出这些宏。

答案 1 :(得分:0)

如果你愿意给你的操作员一个文字名称,你当然可以做1,2,3。我相信4是模板的用途,即带有st作为模板参数的std :: vector 。您可以内联任何这些功能。请注意,此代码可能不会通过代码审核,它只是用于您的实验。

#include <iostream>
#include <boost/optional.hpp> // change to <optional> if you have it

#define OPTIONAL_NS boost // change it to std if above is <optional>
using namespace std;

struct Factorial {};
#define FACTORIAL * Factorial()  /* choose operator based on associativity and precedence */

int operator*( const int n, const Factorial& )
{
    return n == 0 ? 1 : (n - 1) FACTORIAL * n;
}

template<typename T, typename U>
struct StoreOne
{
    const U m_a;

    StoreOne( const U& a )
    : m_a( a )
    {
    }

    operator bool() const // do this only if U can be casted to bool
    {
        return m_a;
    }
};

struct Divides {};
#define DIVIDES * Divides() *

StoreOne<Divides, int> operator*( const int a, const Divides& )
{
    return a;
}

bool operator*( const StoreOne<Divides, int> da, const int b )
{
    return b % da.m_a == 0;
}

struct Gt {};
#define GT < Gt() <

StoreOne<Gt, OPTIONAL_NS::optional<int> > operator<( const OPTIONAL_NS::optional<int> a, const Gt& )
{
    return OPTIONAL_NS::optional<int>( a );
}

OPTIONAL_NS::optional<int> operator<( const StoreOne<Gt, OPTIONAL_NS::optional<int> >& ga, const int b )
{
    if ( ga.m_a )
    {
        if ( *ga.m_a < b )
        {
            return OPTIONAL_NS::optional<int>( b );
        }
    }
    return OPTIONAL_NS::optional<int>();
}

template<typename T>
void printVector( const std::vector<T>& v )
{
    for ( const T& t : v )
    {
        cout << t << endl;
    }
}

int main() {
    cout << endl << "Factorial:      " << ( 5 FACTORIAL                             );
    cout << endl << "Divides:        " << ( 5 DIVIDES 120    ? "Success" : "Failed" );
    cout << endl << "Greater-than 1: " << ( 3 GT 4 GT 5      ? "Success" : "Failed" );
    cout << endl << "Greater-than 2: " << ( !( 3 GT 4 GT 3 ) ? "Success" : "Failed" );
    cout << endl << "Greater-than 3: " << ( !( 5 GT 4 GT 5 ) ? "Success" : "Failed" );
    cout << endl;

    std::vector<int> v;
    v.push_back( 1 );
    v.push_back( 2 );
    v.push_back( 3 );
    printVector( v );
}