c ++如何获得构造函数的数量?
c++ How to get arity of a constructor?
给定一个模板参数 class T
,它有一个 单个 构造函数(也没有复制或移动构造函数) 和 zero 默认参数,有什么方法可以找到 T(...)
的元数吗?
我目前的尝试
#include <iostream>
#include <string>
#include <vector>
template <typename F> struct function_arity;
template <typename R, typename... Args>
struct function_arity<R (Args...)>
: std::integral_constant<std::size_t, sizeof...(Args)> {};
template <typename R, typename... Args>
struct function_arity<R (*)(Args...)> : function_arity<R (Args...)> {};
template <typename R, typename... Args>
struct function_arity<R (&)(Args...)> : function_arity<R (Args...)> {};
template <typename R, typename C, typename... Args>
struct function_arity<R (C::*)(Args...) const> : function_arity<R (Args...)> {};
template <typename R, typename C, typename... Args>
struct function_arity<R (C::*)(Args...)> : function_arity<R (Args...)> {};
template <typename C>
struct function_arity : function_arity<decltype(&C::operator())> {};
struct no_copy { no_copy() = default; no_copy(const no_copy&) = delete; };
struct no_move { no_move() = default; no_move(no_move&&) = delete; };
struct A : no_copy, no_move { A(int, float) { std::cout << "A!\n"; }; };
struct B : no_copy, no_move { B(double) { std::cout << "B!\n"; }; };
struct C : no_copy, no_move { C() { std::cout << "C!\n"; }; };
int main()
{
std::cout << function_arity<&A::A>::value << "\n";
return 0;
}
如果我们做以下假设:
- 参数要么是固定类型,要么是(完全不受限制!)包罗万象的参数(不是
std::basic_string<CharT>
)
- 参数为MoveConstructible
,然后
#include <type_traits>
#include <utility>
namespace detail {
template <typename Ignore>
struct anything {
template <typename T,
typename=std::enable_if_t<not std::is_same<Ignore, std::decay_t<T>>{}>>
operator T&&();
};
template <typename U, typename=void, typename... args>
struct test : test<U, void, args..., anything<U>> {};
template <typename U, typename... args>
struct test<U, std::enable_if_t<std::is_constructible<U, args...>{}
&& sizeof...(args) < 32>, args...>
: std::integral_constant<std::size_t, sizeof...(args)> {};
template <typename U, typename... args>
struct test<U, std::enable_if_t<sizeof...(args) == 32>, args...>
: std::integral_constant<std::size_t, (std::size_t)-1> {};
}
template <typename U>
using ctor_arity = detail::test<U, void>;
…应该按预期工作。 Demo.
请注意,上述方法很容易转换为 C++11。
给定一个模板参数 class T
,它有一个 单个 构造函数(也没有复制或移动构造函数) 和 zero 默认参数,有什么方法可以找到 T(...)
的元数吗?
我目前的尝试
#include <iostream>
#include <string>
#include <vector>
template <typename F> struct function_arity;
template <typename R, typename... Args>
struct function_arity<R (Args...)>
: std::integral_constant<std::size_t, sizeof...(Args)> {};
template <typename R, typename... Args>
struct function_arity<R (*)(Args...)> : function_arity<R (Args...)> {};
template <typename R, typename... Args>
struct function_arity<R (&)(Args...)> : function_arity<R (Args...)> {};
template <typename R, typename C, typename... Args>
struct function_arity<R (C::*)(Args...) const> : function_arity<R (Args...)> {};
template <typename R, typename C, typename... Args>
struct function_arity<R (C::*)(Args...)> : function_arity<R (Args...)> {};
template <typename C>
struct function_arity : function_arity<decltype(&C::operator())> {};
struct no_copy { no_copy() = default; no_copy(const no_copy&) = delete; };
struct no_move { no_move() = default; no_move(no_move&&) = delete; };
struct A : no_copy, no_move { A(int, float) { std::cout << "A!\n"; }; };
struct B : no_copy, no_move { B(double) { std::cout << "B!\n"; }; };
struct C : no_copy, no_move { C() { std::cout << "C!\n"; }; };
int main()
{
std::cout << function_arity<&A::A>::value << "\n";
return 0;
}
如果我们做以下假设:
- 参数要么是固定类型,要么是(完全不受限制!)包罗万象的参数(不是
std::basic_string<CharT>
) - 参数为MoveConstructible
,然后
#include <type_traits>
#include <utility>
namespace detail {
template <typename Ignore>
struct anything {
template <typename T,
typename=std::enable_if_t<not std::is_same<Ignore, std::decay_t<T>>{}>>
operator T&&();
};
template <typename U, typename=void, typename... args>
struct test : test<U, void, args..., anything<U>> {};
template <typename U, typename... args>
struct test<U, std::enable_if_t<std::is_constructible<U, args...>{}
&& sizeof...(args) < 32>, args...>
: std::integral_constant<std::size_t, sizeof...(args)> {};
template <typename U, typename... args>
struct test<U, std::enable_if_t<sizeof...(args) == 32>, args...>
: std::integral_constant<std::size_t, (std::size_t)-1> {};
}
template <typename U>
using ctor_arity = detail::test<U, void>;
…应该按预期工作。 Demo.
请注意,上述方法很容易转换为 C++11。