Không, gói phải là cuối cùng.
Nhưng bạn có thể giả mạo nó. Bạn có thể phát hiện loại cuối cùng trong gói là gì. Nếu là SomeSpecialType
, bạn có thể chạy func của mình. Nếu không phải là SomeSpecialType
, bạn có thể tự gọi mình bằng các đối số được chuyển tiếp và fromNum(5)
được nối thêm.
Nếu bạn muốn được ưa thích, kiểm tra này có thể được thực hiện tại thời gian biên dịch (tức là, một quá tải khác nhau) bằng cách sử dụng kỹ thuật SFINAE. Nhưng điều đó có lẽ không đáng lo ngại, xem xét việc kiểm tra "run-time" sẽ không đổi trên một tình trạng quá tải, và do đó chắc chắn sẽ được tối ưu hóa, và SFINAE không nên được sử dụng một cách nhẹ nhàng.
Điều này không cung cấp cho bạn chữ ký bạn muốn, nhưng nó cung cấp cho bạn hành vi bạn muốn. Bạn sẽ phải giải thích chữ ký dự định trong các bình luận.
Something như thế này, sau khi bạn loại bỏ lỗi chính tả và những thứ tương tự:
// extract the last type in a pack. The last type in a pack with no elements is
// not a type:
template<typename... Ts>
struct last_type {};
template<typename T0>
struct last_type<T0> {
typedef T0 type;
};
template<typename T0, typename T1, typename... Ts>
struct last_type<T0, T1, Ts...>:last_type<T1, Ts...> {};
// using aliases, because typename spam sucks:
template<typename Ts...>
using LastType = typename last_type<Ts...>::type;
template<bool b, typename T=void>
using EnableIf = typename std::enable_if<b, T>::type;
template<typename T>
using Decay = typename std::decay<T>::type;
// the case where the last argument is SomeSpecialType:
template<
typename... Args,
typename=EnableIf<
std::is_same<
Decay<LastType<Args...>>,
SomeSpecialType
>::value
>
void func(Args&&... args) {
// code
}
// the case where there is no SomeSpecialType last:
template<
typename... Args,
typename=EnableIf<
!std::is_same<
typename std::decay<LastType<Args...>>::type,
SomeSpecialType
>::value
>
void func(Args&&... args) {
func(std::forward<Args>(args)..., std::move(static_cast<SomeSpecialType>(fromNum(5))));
}
// the 0-arg case, because both of the above require that there be an actual
// last type:
void func() {
func(std::move(static_cast<SomeSpecialType>(fromNum(5))));
}
hoặc một cái gì đó nhiều như thế.
Vì vậy, nó giống như một cách giải quyết khác, đó là một chữ ký khác nhưng hành vi tương tự ... tôi hiểu. Trên thực tế tôi đã có kế hoạch để loại bỏ thông số đó trong tương lai, vì vậy có lẽ nó không có giá trị nỗ lực (và chữ ký sẽ gây nhầm lẫn). Bạn có thể chỉ cho tôi một ví dụ đơn giản không? – cfa45ca55111016ee9269f0a52e771
@ fr33domlover Tôi phác họa ra thiết kế. Đã không được biên soạn, hãy để một mình gỡ lỗi, nhưng các nguyên tắc cơ bản nên ở đó. – Yakk
Cảm ơn, tôi sẽ thử nếu tôi không quyết định xóa tham số đơn lẻ. Nó trông phức tạp, và chữ ký không được giữ, vì vậy nó có thể không có giá trị rắc rối ... anyway nhờ – cfa45ca55111016ee9269f0a52e771