2013-10-28 57 views
8

如何定義運算符**,使其能夠執行2個數的指數運算。例如2 ** 3。它應該給答案爲8.在C++中定義運算符**

或間接有什麼辦法可以做到這一點與運算符重載而不是#define宏?

+1

http://www.stroustrup.com/bs_faq2.html#overload-operator –

+0

只需使用[pow](http://www.cplusplus.com/reference/cmath/pow/) – Inverse

回答

18

你不能。您只能重載現有的運算符,而不能用於內置類型。

+0

我想知道(因爲我不喜歡不知道)如果C++ 14不透明typedef可以模擬內置類型來實現OP願意實現的目標。 –

+0

@PaperBirdMaster文字數字將始終具有類型「int」。你可能能夠使用用戶定義的文字和東西,但是像'2 ** 16'這樣簡單的東西將永遠不會工作。 –

+0

@ n.m。我知道你對文字的看法(這可能不僅僅是int),但我只是想知道/幻想'opaque typedef's,並且它們是否可以用於像OP想要的東西:'supertypedef int potato ;'和一個免費的操作符:'土豆操作符*(const potatoe a,const potatoe b){return std :: pow(a,b); }'但是現在我寫這個事件看起來很愚蠢事件 –

8

你不能。您只能在C++中重載現有的運算符;你不能添加新的,或者改變現有操作員的秩序或關聯性。即使預處理器在這裏也是無能爲力 - 它的標識符不能是符號。

+9

當然,你可以使用'named operator idiom'定義新的https://github.com/klmr/named-operator – sehe

+1

@sehe Mind:吹。我習慣於元編程和東西,但是這種運算符重載的使用甚至從來沒有超過我的想法。我喜歡你的鏈接問題。 – Angew

+0

@ sehe這是一個很好的習慣用語,我自己(重新)在2005年左右發現了它,但它無法以正確的優先級和相關性定義權力運營商。 –

0

您不能重載內置類型的運算符。我會使用operator ^用於自定義類型的此類用途。

+0

仍然無法完成內置類型。 – StoryTeller

+3

請不要。 '^'有錯誤的優先順序。 –

+0

我不會。首先,它有錯誤的優先順序。對於兩個,沒有。就是不行。 – Xeo

0

不幸的是,可以在C++中重載的運算符集合是固定的,並且不包含**運算符。您可能會考慮使用operator^()來代替,但事實證明^具有錯誤的優先級以充當指數運算符。

簡而言之,不幸的是,您無法做到這一點。

3

正如其他人所指出的:這是不可能的。您可以重載另一個運算符,例如^來取指數,而不是使用簡單類型的包裝類/對象。

但是,如果您喜歡冒險,另一種方法是創建一個支持即時計算這種操作符的微型DSL。 (A famous example of that is LISP in C++)

但是,考慮到所付出的努力,它可能或可能不是你的一杯茶。但是,值得了解的是這種可能性存在。

UPDATE:

操作符重載超載現有運營商的作品。爲什麼?因爲如果你可以定義你自己的,你還必須定義這些操作符的優先級,這些操作符可以很容易地讓位於濫用操作符,通過提取它們的原始目的 - 這會增加讀代碼時的難度。 (至少這是做出的論點)。

具有接近**的語義含義的最接近的運算符是插入符號運算符。這種運營商的天真和說明性實施是:

#include <iostream> 
#include <cmath> 

class Int { 
public: 
    Int() {} 
    Int(int i) : value(i) {} 

    friend double operator^(const int& i, const Int& integer); 
    friend double operator^(const Int& integer, const int& i); 
    friend double operator^(const Int& lhs, const Int& rhs); 
private: 
    int value; 
}; 

double operator^ (const int& lhs, const Int& rhs) { 
    return std::pow(lhs, rhs.value); 
} 

double operator^ (const Int& lhs, const int& rhs) { 
    return std::pow(lhs.value, rhs); 
} 

double operator^ (const Int& lhs, const Int& rhs) { 
    return std::pow(lhs.value, rhs.value); 
} 


int main() { 
    Int i1 = 10; 
    Int i2 = 3; 
    double result = i1^i2; 

    std::cout << result; 
    return 0; 
} 
+0

有沒有什麼辦法可以讓2 ** 3調用一個函數讓我們說mypow(int,int); ? – poorva

+0

@poorva:已更新。 – jrd1

+0

其實在Bjarne Stroustrup的C++編程語言中,我遇到了這個問題 - 定義一個類索引來保存指數函數mypow(double,index)的索引。找到一個方法來讓2 ** 1調用mypow(2,1 ) – poorva

5

如果你願意作出妥協w.r.t. **,感覺像混淆代碼:

#include <cmath> 
#include <iostream> 

struct foo { 
    foo(int i) : i_(i) {} 
    int operator*(int exp) 
    { 
     return std::pow(i_,exp); 
    } 
private: 
    int i_; 
}; 

struct bar { 
} power_of; 

foo operator*(int i, bar) 
{ 
    return foo{i}; 
} 


int main() 
{ 
    std::cout << 2 *power_of* 3; // prints 8 
} 

否則,只需使用std::pow

+0

可以添加'#define $$ * power_of *',所以它會是'2 $$ 3'。另外,我會使用從右到左的關聯運算符,如'* =',所以'4 $$ 3 $$ 2'的結果將是'262144'。 [** DEMO **](http://ideone.com/Nb1H3R) –

5

像注意到其他的答案,這是不可能的內置類型你能得到這個自定義類型的工作,像這樣(最小的代碼示例):

#include <cmath> 
#include <iostream> 

struct dummy; 

struct Int 
{ 
    int i; 
    Int() : i(0) {} 
    Int(const int& i) : i(i) {} 
    dummy operator*(); 
}; 

struct dummy 
{ 
    Int* p; 
    dummy(Int* const p) : p(p) {} 

    int& operator*() 
    { 
     return p->i; 
    } 
}; 

dummy Int::operator*() 
{ 
    return dummy(this); 
} 

int operator*(const Int& lhs, const dummy& rhs) 
{ 
    return std::pow(lhs.i, rhs.p->i); 
} 


int main() 
{ 
    Int a(2); 
    Int b(2); 
    std::cout<< a ** b << std::endl; 
} 

Live example

+2

[類似的方式](http://pastebin.com/6fd5FTp4) – poorva

+0

@poorva:實際上看起來比我的版本更清潔。好一個 ! – user1233963