2016-06-10 83 views
-1

我想知道是否可以在C++中使用宏或内联函数执行4个操作。在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:符号不需要|要么 !。既然他们工作,他们可以是@或$或任何东西。这个想法是后缀(a @),中缀(a @ b),顺序(a @ b @ c)和foreach可能不同,只是小于正常值而已。

+1

**不要使用宏**,你只是为这些片段提供内嵌的功能。 –

+0

宏在这里不能使用,因为它们的名字必须是标识符(不是'''等操作符)。而C++不允许运算符重载内建类型。我想你可以用你自己的特殊预处理器来完成这个任务,但是在那个时候,你并不是真的在写C++,所以你不妨使用不同的语言或者更传统的语法。 – Cameron

+0

我很好奇,如果我可以做到这一点......如果语法与所示相同,我不在乎它的宏或内联......但我更喜欢宏,因为它的代码较小,符号可以是除了那些被禁止的,没有问题的那个 – Daniel

回答

0

如果你愿意给你的操作员一个文本的名字,你当然可以做1,2,3。我相信4是模板的用途,即把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); 
} 
+0

特殊的对象,而其他人只是downvoted或者说,这是无用的和不应该做的,你是唯一一个人回答。谢谢 ! – Daniel

+1

:)高兴地帮助和..不,这不是一个'傻'的问题。诚然,当你是一个团队中的C++程序员时,你不会用这种方式编写代码,但是当你为一群人(非C++员工,比如说科学家,经济学家)实现特定于任务的DSL时,那么采用它们的语法是非常有用和自然的。通过这种方式C++非常强大,您可以重新实现几乎任何语法标记都是文本的语法。快乐的试验:)! – lorro

1
  1. 否,你可以创建一个像int factorial(int x)这样的函数并使用printf(.. factorial(...,但是你不能从宏创建这样的运算符。
  2. 不,|已经是一个运算符(按位或)。
  3. 无论如何,情况就是如此。所以你想做什么?
  4. 为什么?只需使用自动?

我认为你正面临X Y problem.有可能没有理由使这些宏成为任何宏。