如何有条件地定义默认构造函数
How can I conditionally define the default-constructor?
我在想一个这样的类:
template < typename ...Whatever >
class MyClass
{
public:
static constexpr bool has_default_ctr = Something;
// I want this only if "has_default_ctr" is "true".
MyClass();
//...
};
我认为我不能为此使用构造函数模板和std::enable_if
(因为没有参数)。 我错了吗? 如果没有,还有其他方法可以做到这一点吗?
C++11 允许(可靠地)在模板参数中使用enable_if
样式的 SFINAE:
template<
// This is needed to make the condition dependent
bool B = has_default_ctr
, typename std::enable_if<B, int>::type = 0
>
MyClass();
// When outside of class scope:
// have to repeat the condition for out-of-line definition
template<bool B, typename std::enable_if<B, int>::type = 0>
MyClass::MyClass()
/* define here */
在 C++03 中,您可以使用带有默认参数的一元构造函数 - 默认参数意味着构造函数仍算作默认构造函数。
由于评论中提到了带有默认参数的解决方案,但我需要相当长的时间来弄清楚如何做到这一点(将我的 Enabler 类设为私有,这不起作用),这里有建议的解决方案,以防有人正在寻找它:
class MyClass {
public:
// if constructor is supposed to be public,
// this helper class must be public as well!
struct Enabler {};
template <class U = Enabler>
MyClass (std::enable_if_t<has_default_ctr, U> = Enabler {})
{
// whatever
}
};
若要根据某些条件获取类的不同定义,请将依赖项计算放在模板参数中。
// primary template, no default constructor unless Something is true
template< typename T, bool has_default_ctr = Something > class MyClass {
// as you had it, with no default constructor
};
// you want MyClass<T,true> to be just like MyClass<T,false>
// but with a default constructor:
template< typename T > class MyClass<T,true> : public MyClass<T,false> {
MyClass() : MyClass<T,false>(/* chosen constructor args */) { etc; }
using MyClass<T,false>::MyClass<T,false>;
};
如果没有 C++11,则无法使用 using
构造函数继承,并且必须重新声明其所有构造函数并将其参数转发到基类。
这是手指到键盘,我没有编译器方便的 atm,所以有点小的语法错误。
做一些简单的事情,比如
template < typename ...Whatever >
class MyClass
{
public:
static constexpr bool has_default_ctr = Something;
// I want this only if "has_default_ctr" is "true".
MyClass()
{
static_assert(has_default_ctr, "Not Default Constructible");
}
//...
};
最近使用的那个。如果数据成员支持默认构造函数,我需要具有默认构造函数的类模板,否则默认构造函数不应编译。
类模板定义模板类型参数,类定义此类类型的数据成员(使用继承的变体也可能很有吸引力,因为它可以使用空的基类优化)。数据成员的默认构造函数由类的默认构造函数自动调用。如果数据成员的类型没有默认构造函数,则编译将失败。否则它成功。这是代码:
#include <string>
template <typename Data>
class Demo
{
Data d_data;
public:
Demo() = default; // OK when used and Data has a default
// constructor.
Demo(Data const &data) // Exampe of an additional constructor
:
d_data(data)
{}
// ...
};
struct WithoutDefault
{
WithoutDefault(int)
{}
};
int main()
{
Demo<std::string> withString;
// Demo<NoDefault> nope; // won't compile
WithoutDefault nod(10);
Demo<WithoutDefault> nodefault(nod); // OK
}
有了enable_if
就很容易了(如果类也模板化,它也可以工作):
#include <type_traits>
class MyClass
{
public:
static constexpr bool has_default_ctr = Something;
// I want this only if "has_default_ctr" is "true".
template <typename = std::enable_if<has_default_ctr>::type>
MyClass();
//...
};
可能回答不完全是这个问题.但是,如果只想在其模板参数类型字段具有默认构造函数时为模板类启用默认构造函数。然后,您可以在模板类中创建显式默认构造函数。请参阅示例:
struct HasDefault
{
HasDefault() = default;
HasDefault(int) {}
};
struct NoDefault
{
NoDefault() = delete;
NoDefault(int) {}
};
template <typename ValueT>
struct Wrapper
{
Wrapper() = default;
Wrapper(ValueT &&value) : value(std::forward<ValueT>(value)) {}
ValueT value;
};
int main()
{
Wrapper<HasDefault> hasDefault;
Wrapper<HasDefault> hasDefault2(1);
//Wrapper<NoDefault> noDefault; error: use of deleted function 'Wrapper<ValueT>::Wrapper()
Wrapper<NoDefault> noDefault2(1);
}
您可以使用具有不同参数的不同构造函数
MyClass(){
}
MyClass(int num){
}
MyClass(String s){
}
以及 You Can 简单的写入和静态函数,该函数返回类并将条件写入其中:
static chooseContructor(/*parameters*/){
if(/*something*/){
return new MyCLass();
}
else if(/*something else*/){
return new MyClass(int num);
}
else if{
return new MyClass(String s);
}
}
等等...类似的东西会给你一个半自动的构造函数选择器
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 初始化具有非默认构造函数的std::数组项的更好方法
- 具有默认模板类型的默认构造函数的类型推导
- 如何使用非默认构造函数实例化模板化类
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 声明没有默认构造函数的字段
- 没有默认构造函数作为模板参数的自定义比较器
- C++17 没有默认构造函数的地图放置(私有默认构造函数)
- 使用移动调用对等构造函数unique_ptr默认构造函数
- C++复制构造函数和默认构造函数
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 为什么即使我调用参数化构造函数也会调用默认构造函数?
- 具有非默认构造函数的单例类
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 如何处理没有默认构造函数但在另一个构造函数中构造的对象?
- 在C++中使用默认构造函数初始化对象的不同方法
- 在没有默认构造函数的情况下创建的派生对象
- 强制使用默认构造函数对成员进行未初始化的声明
- 使用默认构造函数初始化对象的不同方法
- 创建类类型的动态分配数组,其中类不得具有默认构造函数