将可变参数模板参数与简单的模板参数一起使用时,我在is_base_of从绑定仿函数实例化时遇到了一些奇怪的行为。
这是代码:
template <class T, class Index>
class Base{};
template<typename T>
struct Checker {
typedef int result_type;
// Returns 1 if a given T type is descendant of Base<T,First>
template<typename First, typename ...Args>
result_type operator()(First&& first, Args&&... params)
{
return check(std::is_base_of<Base<T,First>, T>(),
std::forward<First>(first),
std::forward<Args>(params)...);
}
template<typename ...Args>
result_type check(const std::true_type&, Args&&... params)
{
return 1;
}
template<typename ...Args>
result_type check(const std::false_type&, Args&&... params)
{
return 0;
}
};
struct A {};
struct B : Base<B,int> {};
int main()
{
Checker<A> ch1;
std::cout<<ch1(3.14)<<std::endl;
Checker<B> ch2;
std::cout<<ch2(1 ,3.14)<<std::endl; // output is 1
std::cout<<std::bind(ch2, 1, 3.14)()<<std::endl; // output is 0 but it should be 1 !
return 0;
}
程序输出为:
0
1
0
但我希望:
0
1
1
我是否以错误的方式使用可变参数模板?有没有其他(正确的)方法来获得像 Args 这样的可变参数类型列表的第一种类型?为什么只有在与绑定表达式一起使用时才会出现问题?
请注意,如果我将 Base 模板修改为只有一个模板参数,则绑定表达式有效:
template <class T>
class Base{};
template<typename T>
struct Checker {
typedef int result_type;
// Returns 1 if a given T type is descendant of Base<T>
template<typename ...Args>
result_type operator()(Args&&... params)
{
return check(std::is_base_of<Base<T>, T>(),
std::forward<Args>(params)...);
}
template<typename ...Args>
result_type check(const std::true_type&, Args&&... params)
{
return 1;
}
template<typename ...Args>
result_type check(const std::false_type&, Args&&... params)
{
return 0;
}
};
struct A {};
struct B : Base<B> {};
int main()
{
Checker<A> ch1;
std::cout<<ch1(3.14)<<std::endl;
Checker<B> ch2;
std::cout<<ch2(3.14)<<std::endl; // output is 1
std::cout<<std::bind(ch2, 3.14)()<<std::endl; // output is 1 this time!
return 0;
}