std::enable_if 基于可变参数模板的存在
std::enable_if based on variadic template existence
我想创建对象创建器类,它将 ClassType 及其构造函数参数作为模板参数。
在基础知识中,我的代码如下所示:
template<typename ClassType, typename ... Args>
class ClassCreator : public ClassType
{
std::tuple<Args ...> args_;
public:
template <typename std::enable_if<sizeof...(Args)!=0>::type>
ClassCreator(Args ... args) : args_(std::make_tuple(args ...)), ClassType(args ...){}
template <typename std::enable_if<sizeof...(Args)==0>::type>
ClassCreator() : ClassType(){}
template <typename std::enable_if<sizeof...(Args)!=0>::type>
ClassType getObject() const
{
return ClassType(std::get<sizeof...(Args)>(args_) ... );
}
template <typename std::enable_if<sizeof...(Args)==0>::type>
ClassType getObject() const
{
return ClassType();
}
};
有std::enable_if
防护,避免空tuple
std::get<0>
。
我正在将其与示例类一起使用:
class A
{
public:
A(){}
A(int firstInt, int secondInt){}
};
int main()
{
ClassCreator<A> creatorATrivial();
ClassCreator<A, int, int> creatorA(1, 2);
A aTrivial = creatorATrivial.getObject();
A a = creatorA.getObject();
}
我收到很多错误。我是否正确理解sizeof...
运算符?std::get<sizeof...(Args)>(args_) ...
是解压缩tuple
的有效方法吗?
问题在于,SFINAE 仅在替换的直接上下文中才有 n ot anerror。在这里的示例中:
template<typename ClassType, typename ... Args>
class ClassCreator : public ClassType
{
template <typename std::enable_if<sizeof...(Args)!=0>::type>
ClassCreator(Args ... args)
Args...
不在构造函数的直接上下文中,因此替换将立即执行,并且发起的函数将是enable_if<true>::type
或enable_if<false>::type
,后者格式不正确。
还有这个:
return ClassType(std::get<sizeof...(Args)>(args_) ... );
格式不正确。第二个...
没有要扩展的包。解决此问题的常用方法是使用索引序列技巧。对于 C++17,我们也有 std::apply
,在这种情况下将是:
return std::apply([](auto const&... elems){ return ClassType(elems...); },
args_);
<小时 />做一个类创建者来存储参数,然后传递它们的最简单方法是:
template <class T>
class ClassCreator {
std::function<T()> creator;
public:
// as improvements, add perfect forwarding
template <class... Args,
std::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
ClassCreator(Args... args) {
creator = [=]{ return T(args...); };
}
T getObject() const {
return creator();
}
};
ClassCreator<A> creatorATrivial();
ClassCreator<A> creatorA(1, 2); // no <int, int> necessary
A aTrivial = creatorATrivial.getObject();
A a = creatorA.getObject();
相关文章:
- 模板化检查是否存在带有参数列表的类成员函数?
- 构造函数 (C++) 中的 char 指针参数存在问题
- 为什么当函数参数未定义为常量引用时存在无限递归?
- C++20 概念 如何定义带有参数的函数的存在?
- 使用聚合初始化模拟默认函数参数是否存在任何陷阱?
- 在存在错误代码的情况下输出参数与 NRVO
- 如何检查运算符 != 模板参数是否存在 C++ 17?
- 在 mingw64-gcc 上可能存在可变参数的错误
- 当元组给出参数时,如何检查方法是否存在?
- 如果存在具有不同参数的继承成员,为什么对 C++ 结构函数的调用不明确?
- 哪个编译器(如果有的话)在参数包扩展中存在错误
- Clang和GCC在转换C++17中非类型模板参数的自动说明符中存在分歧
- 为什么与非类型参数相反,为什么不可见/存在模板类型参数
- 从返回函数中推断不存在的模板参数
- 错误:"参数"没有命名类型,.cpp和 .h 文件可能存在问题
- CUDA9.2及以上版本中模板默认参数存在无法解决的外部函数错误
- 在 c++ 中具有多个参数构造函数的模板类存在问题
- std::enable_if 基于可变参数模板的存在
- 不存在的标识符在非启用函数模板中用作默认参数
- 是否存在只返回其参数的std函数