【发布时间】:2018-07-15 05:25:00
【问题描述】:
我有一个带有复制构造函数的类,该构造函数仅在满足条件时才启用,例如在此示例中,当类型参数不是引用时。还有一个既不能移动也不能复制的成员(比如互斥锁)。 例如(https://wandbox.org/permlink/hRx51Ht1klYjN7v5)
#include <iostream>
#include <tuple>
#include <mutex>
using std::cout;
using std::endl;
template <typename T>
class Something {
public:
Something() {}
template <typename Type = T,
std::enable_if_t<!std::is_reference<Type>{}>* = nullptr>
Something(const Something&) {}
Something& operator=(Something&&) {
return *this;
}
std::mutex mutex_;
};
int main() {
auto&& one = Something<int>{};
auto two = one;
std::ignore = two;
}
当我编译这段代码时,我得到一个错误提示
copy constructor is implicitly deleted because 'Something<int>' has a user-declared move assignment operator
Something& operator=(Something&&) {
^
1 error generated.
好的,所以我尝试对移动赋值运算符应用相同的约束
template <typename T>
class Something {
public:
Something() {}
template <typename Type = T,
std::enable_if_t<!std::is_reference<Type>{}>* = nullptr>
Something(const Something&) {}
template <typename Type = T,
std::enable_if_t<!std::is_reference<Type>{}>* = nullptr>
Something& operator=(Something&&) {
return *this;
}
std::mutex mutex_;
};
错误改成这个
copy constructor of 'Something<int>' is implicitly deleted because field 'mutex_' has an inaccessible copy constructor
std::mutex mutex_;
^
1 error generated.
有什么想法可以解决这个问题吗?当我明确想要默认构造不可移动不可复制成员时,为什么编译器会抱怨?当我删除约束时,这编译得很好https://wandbox.org/permlink/daqWAbF40MyfDJcN
【问题讨论】:
-
您的 SFINAE 每次都失败。你的意思是
std::is_reference_v或std::is_reference<Type>::value;您当前的尝试将operator!应用于没有它的结构,因此无论它是否是引用类型都会遇到替换失败。 -
@DanielH 并非如此,这适用于隐式整数转换, std::integral_constant 可转换为其相应的整数类型。在本例中为布尔值。
-
糟糕,是的,我检查了,但仍然没有看到。我的错。
标签: c++ templates c++14 copy-constructor