不,包必须是最后一个。
但你可以伪造它。您可以检测包装中的最后一种类型。如果它是SomeSpecialType
,你可以运行你的func。如果它不是SomeSpecialType
,则可以递归地调用你自己的转发参数并附加fromNum(5)
。
如果您想要使用SFINAE技术,可以在编译时(即不同的超载)完成此项检查。但是这可能是不值得的麻烦,考虑到“运行时间”检查将在给定的过载情况下保持不变,因此几乎肯定会被优化,而SFINAE不应该被轻易使用。
这不会给你你想要的签名,但它会给你你想要的行为。您必须在评论中解释预期的签名。
这样的事情,以后你删除错别字和其他:
// 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))));
}
或东西很像。
所以这就像一个解决方法,它是一个不同的签名,但是同样的行为......我明白了。实际上,我打算在将来删除这个参数,所以也许这不值得(但签名会令人困惑)。你能告诉我一个简单的例子吗? – cfa45ca55111016ee9269f0a52e771 2013-02-11 02:53:57
@ fr33domlover我勾勒出了设计。尚未编译,更不用说调试了,但基本原理应该在那里。 – Yakk 2013-02-11 03:24:54
谢谢,我会试试看,如果我不只是决定删除单个参数。它看起来很复杂,并且签名没有保存,所以它可能不值得麻烦......无论如何感谢 – cfa45ca55111016ee9269f0a52e771 2013-02-11 03:30:53