Có ba số: 0, 1 và vô cực.
Ồ, và việc đếm bắt đầu từ 0, không phải 1!
template<typename... Ts>
struct first_type {}
template<typename T0, typename... Ts>
struct first_type {
typedef T0 type;
};
template<typename... Ts>
using FirstType = typename first_type<Ts...>::type;
template<typename T0, typename Rest, typename=void>
struct foo_impl;
template<typename... Ts>
struct foo_augment {};
template<typename T1>
struct foo_augment<T1> {
T1 m_t1;
T1 t1() const { return m_t1; }
T1 t1() { return m_t1; }
};
template<typename T0, typename... Ts>
struct foo_impl< T0, std::tuple<Ts...>, typename std::enable_if< (sizeof...(Ts)<2) >::type >:
foo_augment<Ts...>
{
// use FirstType<Ts...> to get at the second type of your argument pack
foo_impl(T0 t0, Ts... ts):
m_t0(t0), foo_augment<Ts...>(ts...)
{};
T0 m_t0;
T0 t0() { return m_t0; }
T0 t0() const { return m_t0; }
};
template<typename T0, typename... Ts>
using foo = foo_impl<T0, std::tuple<Ts...>>;
Bây giờ, lưu ý rằng có rất nhiều mẫu trên, số tiền hợp lý nhiều hơn số lượng mã trùng lặp bạn đã sử dụng.
Thay vì lộn xộn ...
, bạn có thể sử dụng "giá trị được đặt trước" cho T1
để cho biết "không có", như void
. Trong trường hợp đó, bạn có thể sử dụng thủ thuật này với các nhà xây dựng:
template<typename... Ts, typename=typename std::enable_if< ((sizeof...(Ts)==0) == (std::is_same<T1, void>::value)) && (sizeof...(Ts)<2) >::type >
foo_impl(T0 t0, Ts&&... ts):
m_t0(t0), foo_augment<Ts...>(std::forward<Ts>(ts)...)
{};
nơi các nhà xây dựng là variardic, nhưng SFINAE có nghĩa là các gói Ts...
tham số phải là 0 yếu tố khi và chỉ khi T1
là void
, và phải là 1 yếu tố khi và chỉ khi T1
không phải là void
.
(Mã chưa được biên soạn nhưng thiết kế cơ bản phải rõ ràng).
Mã của bạn là có sự mơ hồ nội tại ngoài vấn đề bạn đang cố gắng giải quyết: Đối với mẫu tham số đơn, trình biên dịch sẽ không thể giải quyết mẫu để sử dụng. Ví dụ: http://ideone.com/7wcB6Z – SomeWittyUsername
@icepack Ý của bạn là gì? Mã của bạn không thành công, như mong đợi, bởi vì lớp không có một hàm tạo mặc định? – 7cows