您可以使用特徵來定義的基於它們的類型參數列表接受。
它遵循最小,工作示例:
void _f(int, ...) {}
template<typename...> struct accepts;
template<> struct accepts<int, double, char> {};
template<> struct accepts<int, char, int> {};
template <class... T>
auto f(T... args) -> decltype(accepts<T...>{}, void()) {
_f(args...);
}
int main() {
f(0, 0., 'c');
f(0, 'c', 0);
// f(0, 0, 0);
}
最後invokation會給你一個編譯時錯誤<int, int, int>
不是結構accepts
的有效分工。
這是因爲主模板未定義,您可以通過引入越來越多的專業化(如果需要)來控制接受的列表。
在這裏是基於std::true_type
,std::false_type
和static_assert
稍微不同的解決方案:
#include<type_traits>
void _f(int, ...) {}
template<typename...> struct accepts: std::false_type {};
template<> struct accepts<int, double, char>: std::true_type {};
template<> struct accepts<int, char, int>: std::true_type {};
template <class... T>
void f(T... args) {
static_assert(accepts<T...>::value, "!");
_f(args...);
}
int main() {
f(0, 0., 'c');
f(0, 'c', 0);
// f(0, 0, 0);
}
優點是:
- 一個在編譯時(當然,如果更有意義的錯誤消息用有意義的東西代替
"!"
)
- 可能性t o通過從
std::false_type
繼承並明確地禁用參數列表,並在需要時同時記錄它
缺點是它有點冗長。
哦......'_f'是一種舊式的非模板變量函數。 '...'不僅僅代表你爲了簡潔而省略的東西,它實際上就是C++的特殊功能。是的,那麼我的答案確實無效,所以我刪除了它。 – hvd
無論如何,謝謝。看來我並不太精確。 –
@ hvd我得到了你的答案,並重新使用了一些特徵。也許它現在有效。 – skypjack