2010-02-11 70 views
13

Tất cả đều được kế thừa từ một lớp cơ sở? Tôi có phải sử dụng các mẫu không?Làm cách nào để truyền một trình tạo số ngẫu nhiên C++ 11 cho một hàm?

(tôi đề cập đến những http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c15319/)

tôi đang làm này ngay bây giờ:

typedef std::mt19937 RNG; 

và sau đó

class Chooser { 
public: 
    Chooser(RNG& rng, uint n, uint min_choices, uint max_choices): 

Nói cách khác, tôi đi tham khảo để RNG . Làm thế nào tôi sẽ vượt qua trong một máy phát điện tùy ý?

Ngoài ra, tôi nhận ra đây có thể là một câu hỏi khác, nhưng làm thế nào để chuyển máy phát đến STL?

dường như không hoạt động.


giải pháp cho máy phát điện đi qua:

typedef std::ranlux64_base_01 RNG; 
typedef std::mt19937 RNGInt; 

giải pháp để đi qua để STL:

struct STL_RNG { 
    STL_RNG(RNGInt& rng): gen(rng) {}  
    RNGInt& gen; 
    int operator()(int n) { return std::uniform_int<int>(0, n)(gen); } 
}; 
+0

Theo bài viết đó, họ đã là các functors nên bạn đã sẵn sàng. Có chuyện gì vậy? – Potatoswatter

+0

Chúng tôi có thể sẽ cung cấp thông tin cụ thể và hữu ích hơn nếu chúng tôi biết mục tiêu của bạn. – GManNickG

+0

Cụ thể, bạn muốn máy phát của mình khác nhau như thế nào và lỗi trình biên dịch bạn nhận được cho 'random_shuffle' là gì? – Potatoswatter

Trả lời

10

Chúng không phải tất cả đều được thừa hưởng từ một cơ sở (điều này hơi ngạc nhiên), nhưng không quan trọng vì đó không phải là cách các hàm F ++ hoạt động.

Đối với các RNG tùy ý của một loại đã cho, bạn đã nhận được ngay lúc (giờ) được đăng.

Nếu bạn muốn nói, làm cách nào để tôi xác định một chức năng chấp nhận bất kỳ trình tạo số ngẫu nhiên nào làm đối số.

template< class RNG > // RNG may be a functor object of any type 
int random_even_number(RNG &gen) { 
    return (int) gen() * 2; 
} 

Bạn không cần phải sử dụng thêm bất kỳ mẫu nào khác, vì loại khấu trừ.


Xác định một hàm để chấp nhận RNG khác là phức tạp hơn vì ngữ nghĩa yêu cầu phải có loại cơ sở chung. Bạn cần xác định loại cơ sở.

struct RNGbase { 
    virtual int operator() = 0; 
    virtual ~RGNBase() {}; 
}; 

template< class RNG > 
struct SmartRNG : RNGBase { 
    RNG gen; 

    virtual int operator() { 
     return gen(); 
    } 
}; 

int random_even_number(RNGBase &gen) { // no template 
    return (int) gen() * 2; // virtual dispatch 
} 
+0

thực sự không may, bởi vì nó có nghĩa là tôi phải có tất cả các chức năng ngẫu nhiên của tôi trong các tiêu đề. –

+0

(nhưng cảm ơn câu trả lời ...) –

+0

@Neil: Xem câu trả lời thứ hai của tôi (tôi chỉ cam kết đoạn đầu tiên lúc đầu). Tôi nghĩ rằng ý định của tiêu chuẩn là bạn chọn một máy phát điện và dính vào nó. Không cần thiết cho bất kỳ điều này nếu bạn chỉ muốn sử dụng 'std :: mt19937'… nhưng điều đó không rõ ràng từ câu hỏi của bạn. – Potatoswatter

0

Wrap nó trong một lớp học hoặc functor phù hợp với nhu cầu của bạn?

+0

Có cách tự động để bọc một cái gì đó như thế trong một functor? –

0

Tôi đề xuất hai phương pháp: Đối tượng chức năng và Con trỏ hàm. Trong cả hai trường hợp, cho phép lớp của bạn nhận một đối tượng hàm hoặc một con trỏ hàm tới trình tạo số ngẫu nhiên.

Với đối tượng hàm, bạn có thể xác định lớp cơ sở và lớp nhận của bạn triển khai các hàm yêu cầu trỏ đến lớp đối tượng hàm cơ sở. Điều này cho phép bạn tự do hơn trong việc xác định nhiều đối tượng hàm khác nhau mà không thay đổi giao diện của lớp nhận.

4

gì làm việc cho tôi đã sử dụng một std::function:

#include <functional> 
#include <random> 

void exampleFunction(std::function<int()> rnd) { 
    auto randomNumber = rnd(); 
} 

std::minstd_rand rnd; 
exampleFunction([&rnd](){ return rnd(); }); 

// This won't work as it passes a copy of the object, so you end up with the same 
// sequence of numbers on every call. 
exampleFunction(rnd); 

Bạn đang không thực sự đi qua xung quanh đối tượng ngẫu nhiên, chỉ cần một phương pháp để gọi các đối tượng của operator(), nhưng nó đạt được hiệu quả tương tự. Lưu ý rằng ở đây độ chính xác của giá trị trả về của trình tạo số ngẫu nhiên có thể bị giảm khi std::function được khai báo là trả về int, vì vậy bạn có thể muốn sử dụng loại dữ liệu khác thay vì int tùy thuộc vào nhu cầu của bạn về độ chính xác.

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