所以我非常熟悉测试成员函数是否存在的范式。目前这段代码是有效的:
#include <iostream>
#include <type_traits>
struct has_mem_func_foo_impl {
template <typename U, U>
struct chk { };
template <typename Class, typename Arg>
static std::true_type has_foo(chk<void(Class::*)(Arg), &Class::foo>*);
template <typename, typename>
static std::false_type has_foo(...);
};
template <typename Class, typename Arg>
struct has_mem_func_foo : decltype(has_mem_func_foo_impl::template has_foo<Class,Arg>(nullptr)) { };
struct bar {
void foo(int) { }
};
int main() {
static_assert( has_mem_func_foo<bar, int>::value, "bar has foo(int)" );
}
不幸的是,如果我进行轻微的调整:
#include <iostream>
#include <type_traits>
struct has_mem_func_foo_impl {
template <typename U, U>
struct chk { };
template <typename Class, typename... Arg>
static std::true_type has_foo(chk<void(Class::*)(Arg...), &Class::foo>*);
template <typename, typename...>
static std::false_type has_foo(...);
};
template <typename Class, typename... Arg>
struct has_mem_func_foo : decltype(has_mem_func_foo_impl::template has_foo<Class,Arg...>(nullptr)) { };
struct bar {
void foo(int) { }
};
int main() {
static_assert( has_mem_func_foo<bar, int>::value, "bar has foo(int)" );
}
我的静态断言失败了。我曾经认为可变模板参数包在展开到它们的位置时会被同等对待。无论是gcc还是clang都会产生失败的静态断言。
因此,我的问题的真正根源是,这是标准行为吗?当测试可变模板成员函数是否存在时也会失败。
...Arg
。您传递了第一个Arg
,但它还需要针对每个其他的Arg
进行检查。嗯。如果这是正确的,我想我有一个主意。 - Yakk - Adam Nevraumonttypename... Arg
移动到has_mem_func_foo_impl
模板参数中,像这样。 - Piotr Skotnickiint
。 - cdacamaranullptr_t
推断出来,于是放弃了该重载。 - Yakk - Adam Nevraumont