2016-09-21 20 views
10

Tôi có một hàm mẫu có số lượng đối số thay đổi. Vì bạn không thể ép buộc đối số là một loại nhất định, tôi muốn ít nhất là buộc số lượng đối số không cao hơn số xác định thời gian biên dịch (ví dụ 10).Giới hạn số tham số trong gói tham số mẫu variadic

Có thể làm cho trình biên dịch đưa ra lỗi nếu chức năng mẫu có gói tham số có số đối số cao hơn giá trị được xác định thời gian biên dịch không?

template <class ...Args> 
void setRequestArguments(const Args&... args) 
{ 
    const std::vector<QGenericArgument> vec = { args... }; 
    qDebug() << sizeof...(args); 
    // Do stuff... 
    // for (unsigned i = 0; i < vec.size(); ++i) { 
    //  qDebug() << vec[i].name(); 
    // } 
} 

Tôi muốn sử dụng nó cho một vùng chứa chung cho tất cả các đối số trong hàm chức năng bao bọc QMetaObject::invokeMethod.

+1

có thể giới hạn đối số cho một loại nhất định. Bạn có muốn một câu trả lời về điều này? Bạn có yêu cầu các đối số chính xác là 'T' hoặc một cái gì đó có thể chuyển đổi thành' T' không? – bolov

+0

@bolov Vâng, xin vui lòng, điều đó sẽ cực kỳ hữu ích! Tôi sẽ +1 –

+1

Tôi đã tạo một bài đăng mới với chính xác điều này: http://stackoverflow.com/questions/39659127/restrict-variadic-template-arguments/39659128#39659128 – bolov

Trả lời

20

Để thực hiện các chức năng không thể được gọi khi có quá nhiều đối số, bạn có thể hạn chế các chức năng với sfinae. Bằng cách đó, nếu có quá tải khác chấp nhận nhiều đối số hơn, trình biên dịch sẽ có thể chọn quá tải chính xác.

Một đơn giản std::enable_if với tình trạng này sẽ đủ:

template <class ...Args, std::enable_if_t<(sizeof...(Args) <= 10)>* = nullptr> 
void setRequestArguments(Args&&... args) 
{ 
    const std::vector<QGenericArgument> vec = { std::forward<Args>(args)... }; 
} 

Vì lợi ích của khả năng đọc, bạn có thể đặt các hạn chế trong kiểu trả về dấu của chức năng của bạn:

template <class ...Args> 
auto setRequestArguments(Args&&... args) -> std::enable_if_t<(sizeof...(args) <= 10)> 
{ 
    const std::vector<QGenericArgument> vec = { std::forward<Args>(args)... }; 
} 

EDIT: Tôi đã thêm tham chiếu chuyển tiếp thay vì tham chiếu const, vì nó có thể tăng tốc chương trình và thân thiện hơn với các loại không đồng bộ hóa.

+3

Đó thực sự là một cách thú vị khi sử dụng SFINAE :) – Rakete1111

14

Có thể làm cho trình biên dịch đưa ra lỗi nếu chức năng mẫu có gói tham số có số đối số cao hơn giá trị được xác định thời gian biên dịch không?

Có, sử dụng static_assert:

template <class ...Args> 
void setRequestArguments(const Args&... args) 
{ 
    static_assert(sizeof...(args) <= 10, "You can't have more than 10 arguments!"); 
    //Stuff... 
} 
Các vấn đề liên quan