折叠可变参数模板检查是否存在成员函数
Folding variadic template checking for existence of a member function
我正在使用 SFINAE 习惯用法来检查类型是否具有具有特定签名的方法 (function_name()
)。我实现的解决方案适用于单一类型,但我想让它适用于多种类型(通过可变参数模板)。
template <typename... Other>
class has_foo {
public:
static constexpr bool value = has_foo<Other...>::value;
};
template <typename U, typename ...Other> // Error here
class has_foo {
public:
static constexpr bool value = has_foo<U>::value && has_foo<Other...>::value;
};
template <typename U>
class has_foo {
private:
template <typename T, T>
struct helper;
template <typename T>
static std::uint8_t check(helper<int (*)(size_t), &T::function_name>*);
template <typename T>
static std::uint16_t check(...);
public:
static constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t);
};
template <>
class has_foo<void> {
public:
static constexpr bool value = false;
};
我收到以下错误:too many template parameters in template redeclaration
。我在这里做错了什么?
template <typename U, typename ...Other>
class has_foo {
public:
static constexpr bool value = has_foo<U>::value && has_foo<Other...>::value;
};
// partial template specialization
template <typename... Other>
class has_foo<void, Other...>{
public:
static constexpr bool value = has_foo<void,Other...>::value;
};
// partial template specialization
template <typename U>
class has_foo<U,void> {
private:
template <typename T, T>
struct helper;
template <typename T>
static std::uint8_t check(helper<int (*)(size_t), &T::function_name>*);
template <typename T>
static std::uint16_t check(...);
public:
static constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t);
};
// partial template specialization
template <>
class has_foo<void> {
public:
static constexpr bool value = false;
};
即使我不能测试它,因为它不是 mvce,也许下面的代码适合你。
template<typename... Args>
class has_foo { };
template <typename U, typename ...Other>
class has_foo<U, Other...>: public has_foo<Other...> {
template <typename t, t>
struct helper;
template <typename t>
static std::uint8_t check(helper<int (*)(size_t), &t::function_name>*);
template <typename t>
static std::uint16_t check(...);
public:
static constexpr bool value = (sizeof(check<U>(0)) == sizeof(std::uint8_t)) && has_foo<Other...>::value;
};
template <>
class has_foo<> {
public:
static constexpr bool value = true;
};
template <>
class has_foo<void> {
public:
static constexpr bool value = false;
};
这里是一个精简版,也可以编译:
#include <iostream>
template<typename... Args>
class has_foo { };
template <typename U, typename ...Other>
class has_foo<U, Other...>: public has_foo<Other...> {
public:
static constexpr bool value = true && has_foo<Other...>::value;
};
template <>
class has_foo<> {
public:
static constexpr bool value = true;
};
template <>
class has_foo<void> {
public:
static constexpr bool value = false;
};
int main() {
std::cout << has_foo<int, double, char>::value << std::endl;
std::cout << has_foo<int, double, void>::value << std::endl;
std::cout << has_foo<>::value << std::endl;
}
基本思想是定义一个可变结构,然后专门用于所有需要的情况,让它工作,除了 void
您看起来感兴趣的情况。
目前,returns true
示例中的最后一个案例,我不确定如何处理这个案例,因为您没有给出任何建议。不管怎样,从上面的例子开始,你可以很容易地根据你的要求修改它。
我正在使用 SFINAE 习惯用法来检查类型是否具有具有特定签名的方法 (function_name()
)。我实现的解决方案适用于单一类型,但我想让它适用于多种类型(通过可变参数模板)。
template <typename... Other>
class has_foo {
public:
static constexpr bool value = has_foo<Other...>::value;
};
template <typename U, typename ...Other> // Error here
class has_foo {
public:
static constexpr bool value = has_foo<U>::value && has_foo<Other...>::value;
};
template <typename U>
class has_foo {
private:
template <typename T, T>
struct helper;
template <typename T>
static std::uint8_t check(helper<int (*)(size_t), &T::function_name>*);
template <typename T>
static std::uint16_t check(...);
public:
static constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t);
};
template <>
class has_foo<void> {
public:
static constexpr bool value = false;
};
我收到以下错误:too many template parameters in template redeclaration
。我在这里做错了什么?
template <typename U, typename ...Other>
class has_foo {
public:
static constexpr bool value = has_foo<U>::value && has_foo<Other...>::value;
};
// partial template specialization
template <typename... Other>
class has_foo<void, Other...>{
public:
static constexpr bool value = has_foo<void,Other...>::value;
};
// partial template specialization
template <typename U>
class has_foo<U,void> {
private:
template <typename T, T>
struct helper;
template <typename T>
static std::uint8_t check(helper<int (*)(size_t), &T::function_name>*);
template <typename T>
static std::uint16_t check(...);
public:
static constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t);
};
// partial template specialization
template <>
class has_foo<void> {
public:
static constexpr bool value = false;
};
即使我不能测试它,因为它不是 mvce,也许下面的代码适合你。
template<typename... Args>
class has_foo { };
template <typename U, typename ...Other>
class has_foo<U, Other...>: public has_foo<Other...> {
template <typename t, t>
struct helper;
template <typename t>
static std::uint8_t check(helper<int (*)(size_t), &t::function_name>*);
template <typename t>
static std::uint16_t check(...);
public:
static constexpr bool value = (sizeof(check<U>(0)) == sizeof(std::uint8_t)) && has_foo<Other...>::value;
};
template <>
class has_foo<> {
public:
static constexpr bool value = true;
};
template <>
class has_foo<void> {
public:
static constexpr bool value = false;
};
这里是一个精简版,也可以编译:
#include <iostream>
template<typename... Args>
class has_foo { };
template <typename U, typename ...Other>
class has_foo<U, Other...>: public has_foo<Other...> {
public:
static constexpr bool value = true && has_foo<Other...>::value;
};
template <>
class has_foo<> {
public:
static constexpr bool value = true;
};
template <>
class has_foo<void> {
public:
static constexpr bool value = false;
};
int main() {
std::cout << has_foo<int, double, char>::value << std::endl;
std::cout << has_foo<int, double, void>::value << std::endl;
std::cout << has_foo<>::value << std::endl;
}
基本思想是定义一个可变结构,然后专门用于所有需要的情况,让它工作,除了 void
您看起来感兴趣的情况。
目前,returns true
示例中的最后一个案例,我不确定如何处理这个案例,因为您没有给出任何建议。不管怎样,从上面的例子开始,你可以很容易地根据你的要求修改它。