如何解析工厂函数中的构造函数签名

How to resolve constructor signature in factory function

在下面的 create(...) 函数中创建其实例时,我想支持 class T 的构造函数的两个可能签名之一:

template <class Т, typename... Args>
T* create(Special* s, Args&&... args) {
  T* t = 
    // If such a constructor exists, this:
    new T(s, std::forward<Args>(args)...);
    // Otherwise, this:
    new T(std::forward<Args>(args)...);
}

我尝试了一些没有成功的可怕模板构造。 solution for resolving a member function 涉及 SFINAE 使成员函数的 decltype 失败,但这对于构造函数显然是不可能的,因为它没有自己的签名类型。

这在 C++11 中是否可行,是否有任何库支持?

template <class Т, typename... Args>
T* create_impl(std::true_type, Special* s, Args&&... args) {
  return new T(s, std::forward<Args>(args)...);
}
template <class Т, typename... Args>
T* create_impl(std::false_type, Special*, Args&&... args) {
  return new T(std::forward<Args>(args)...);
}

template <class Т, typename... Args>
T* create(Special* s, Args&&... args) {
   T* t = create_impl<T>(std::is_constructible<T, Special*&, Args&&...>{},
                         s, std::forward<Args>(args)...);
   // ...
   return t;
}

只需使用std::is_constructible:

namespace detail
{
template<typename T, typename... Ts>
auto create(std::true_type, Special* s, Ts&&... args) {
    return new T(s, std::forward<Ts>(args)...);
}

template<typename T, typename... Ts>
auto create(std::false_type, Special*, Ts&&... args) {
    return new T(std::forward<Ts>(args)...);
}

}

template<class T, typename... Args>
T* create(Special* s, Args&&... args) {
    using tag = is_constructible<T, Special*, Args...>;
    return detail::create<T>(tag{}, s, std::forward<Args>(args)...);
}

live demo