2015-12-02 58 views
1

我想實現C++遞歸結構,東西應該看起來有點像這樣:C++ - 遞歸結構 - 有可能嗎?

typedef struct { 
    static constexpr int foo() { 
     return 1; 
    } 
    typedef struct { 
     // not valid - I meant foo() from "type" not from "recursive_type" 
     static constexpr int foo() { 
      return 2 * foo(); 
     } 
     // ? (there should be another recursive type here) 
    } recursive_type; 
} type; 

而且應該像這樣工作:

static_assert(type::foo() == 1, "Nope"); 
static_assert(type::recursive_type::foo() == 2, "Nope"); 
static_assert(type::recursive_type::recursive_type::foo() == 4, "Nope"); 

基本上 - 我想recursive_type遏制結構看起來完全像type,但其foo()返回值爲typefoo()的值的兩倍。但正如我在評論中指出的那樣,我的方法存在一些問題,可惜它不起作用。

這樣的結構可以用C++聲明嗎,或者它不可能?

+0

你會更好地使用指針,也許智能的指針。避免用相同的名稱命名兩個'struct'(在同一個翻譯單元中)。 –

+0

是的,我知道我可以使用指針來做到這一點,但我需要一個對象,其語義看起來像我所描述的。 (所以'recursive_type'應該稍微修改它所調用的對象的修改版本) – qiubit

+0

您是否考慮切換到Ocaml。它有遞歸函子... –

回答

3

是的,從Let_Me_Be貸款,你可以得到你要求的行爲:

template< int tag > 
struct X 
{ 
    static constexpr int foo() { return 2 * X<tag-1>::foo(); } 

    typedef X<tag+1> recursive_type; 
}; 


template< > 
struct X<0> 
{ 
    static constexpr int foo() { return 1; } 

    typedef X<1> recursive_type; 
}; 

typedef X<0> type; 

static_assert(type::foo() == 1, "Nope"); 
static_assert(type::recursive_type::foo() == 2, "Nope"); 
static_assert(type::recursive_type::recursive_type::foo() == 4, "Nope"); 

當然與你可以寫的recursive_type深遞歸用途爲X<n>,而不是獎金...

5

排序這是你在C++中實現類型遞歸的方式。

template< int tag > 
struct X 
{ 
    static constexpr int foo() { return 2 * X<tag-1>::foo(); } 
}; 

template< > 
struct X<1> 
{ 
    static constexpr int foo() { return 1; } 
}; 

#include <iostream> 
using namespace std; 

int main() 
{ 
    static_assert(X<1>::foo() == 1, "Nope"); 
    static_assert(X<2>::foo() == 2, "Nope"); 
    static_assert(X<3>::foo() == 4, "Nope"); 

    cout << X<10>::foo() << endl; 
}