2016-12-06 16 views
7

Tôi nghĩ rằng điều đó là không thể nhưng tôi muốn hỏi bạn trước khi từ bỏ nó.Thủ đoạn Constexpr

Tôi muốn một cái gì đó giống như tăng constexpr.

#include <iostream> 

constexpr int inc() { 

    static int inc = 0; 
    return inc++; 
} 

class Foo { 

    static const int Type = inc(); 
}; 

class Foo2 { 

    static const int Type = inc(); 
}; 

int main() { 

    std::cout << "Foo1 " << Foo1::Type << st::endl; 
    std::cout << "Foo2 " << Foo2::Type << st::endl; 
    return 0; 
} 

tôi muốn gọi nó vào một số lớp không tự (tôi sử dụng CRTP cho điều đó), để cung cấp cho một loại khác nhau để mỗi người trong số họ, nhưng loại cần phải được const. Có cách nào để đạt được một cái gì đó như thế trong C++? (C++ 17 + TS)

+3

* "Tôi nghĩ rằng điều đó là không thể" * Về cơ bản mọi thứ đều có thể với các mẫu C++, đôi khi nó chỉ phức tạp ngu ngốc. –

+0

Tôi không chắc chắn, nhưng tôi nghĩ rằng nó có thể là một phần của C++ 17, nhưng tôi có thể sai – holmicz

+3

Có các macro 'COUNTER' không chuẩn, và có các triển khai các tác dụng phụ biên dịch ([Filip Roseen ] (http://b.atch.se/) đến với tâm trí). Sau này là cực kỳ xấu xí, mặc dù. Tôi muốn thử một cách tiếp cận khác. – dyp

Trả lời

1

Vì vậy, có là giải pháp bởi Filip Roseen gọi là constant-expression counter:

#include <iostream> 

template<int N> 
struct flag { 
    friend constexpr int adl_flag (flag<N>); 
}; 

template<int N> 
struct writer { 
    friend constexpr int adl_flag (flag<N>) { 
    return N; 
    } 

    static constexpr int value = N; 
}; 

template<int N, int = adl_flag (flag<N> {})> 
int constexpr reader (int, flag<N>) { 
    return N; 
} 

template<int N> 
int constexpr reader (float, flag<N>, int R = reader (0, flag<N-1> {})) { 
    return R; 
} 

int constexpr reader (float, flag<0>) { 
    return 0; 
} 

template<int N = 1> 
int constexpr next (int R = writer<reader (0, flag<32> {}) + N>::value) { 
    return R; 
} 

class Foo { 

    public: 
    static const int Type = next(); 
}; 

class Foo2 { 

    public: 
    static const int Type = next(); 
}; 

int main() { 

    std::cout << "Foo1 " << Foo::Type << std::endl; 
    std::cout << "Foo2 " << Foo2::Type << std::endl; 
    return 0; 
} 

Thanks guys :) Nhưng đó là quá mạo hiểm để sử dụng nó trong thư viện chính của tôi sẽ được sử dụng trong mọi dự án.

PS: Tôi sẽ không đóng ngay bây giờ nếu có câu trả lời khác. Bởi vì có nó xấu xí.

Các vấn đề liên quan