可以将 class 对象创建为仅左值吗?
Can a class object be created as an lvalue-only?
std::lock_guard
(及其相关)的一个众所周知的问题是,当仅创建一个临时对象时,它无法按预期方式工作。
例如:
std::mutex mtx;
std::lock_guard<std::mutex> {mtx} // temporary object, does not lock the entire scope
std::lock_guard<std::mutex> lck{mtx} // correct
我尝试使用引用限定符来创建一个替代品,以防止创建临时对象(在编译时)。以下代码是徒劳的尝试:
#include <mutex>
template<typename T>
struct my_lock {
T &mtx;
my_lock(T &t) : mtx{t} { lock(); }
~my_lock() { unlock(); }
void lock() & { mtx.lock(); };
void unlock() & { mtx.unlock(); };
};
std::mutex mtx;
int main()
{
my_lock<std::mutex> {mtx}; // A
my_lock<std::mutex lck{mtx}; // B
}
这行不通,所以问题变成:
是否可以以编译器拒绝 A
并接受 B
的方式编写 class?
如果可以使用c++17
,则可以使用具有工厂功能的[[nodiscard]]
属性。
class [[nodiscard]] my_lock{
my_lock()=default;
friend my_lock lock();
};
[[nodiscard]] my_lock lock(){return {};}
int main(){
{ lock(); } //warning for discard return value
{ auto l = lock();}
}
让我重新解释你的问题,而不是:
Is it possible to write the class in such a way that the compiler rejects A and accepts B ?
我要把它读成
Is it possible for my compiler to reject A and accept B?
是的,这取决于编译器,无需您自己编写 类。我对 clang 非常熟悉,但是,类似的检查将存在于其他编译器或静态分析器中。
对于 clang,-Wunused-value -Werror
就可以了。第一个激活警告,第二个将其提升为错误。
就我个人而言,我赞成启用所有警告并明确禁用那些您有理由不遵守的警告,包括说明原因的文档。
std::lock_guard
(及其相关)的一个众所周知的问题是,当仅创建一个临时对象时,它无法按预期方式工作。
例如:
std::mutex mtx;
std::lock_guard<std::mutex> {mtx} // temporary object, does not lock the entire scope
std::lock_guard<std::mutex> lck{mtx} // correct
我尝试使用引用限定符来创建一个替代品,以防止创建临时对象(在编译时)。以下代码是徒劳的尝试:
#include <mutex>
template<typename T>
struct my_lock {
T &mtx;
my_lock(T &t) : mtx{t} { lock(); }
~my_lock() { unlock(); }
void lock() & { mtx.lock(); };
void unlock() & { mtx.unlock(); };
};
std::mutex mtx;
int main()
{
my_lock<std::mutex> {mtx}; // A
my_lock<std::mutex lck{mtx}; // B
}
这行不通,所以问题变成:
是否可以以编译器拒绝 A
并接受 B
的方式编写 class?
如果可以使用c++17
,则可以使用具有工厂功能的[[nodiscard]]
属性。
class [[nodiscard]] my_lock{
my_lock()=default;
friend my_lock lock();
};
[[nodiscard]] my_lock lock(){return {};}
int main(){
{ lock(); } //warning for discard return value
{ auto l = lock();}
}
让我重新解释你的问题,而不是:
Is it possible to write the class in such a way that the compiler rejects A and accepts B ?
我要把它读成
Is it possible for my compiler to reject A and accept B?
是的,这取决于编译器,无需您自己编写 类。我对 clang 非常熟悉,但是,类似的检查将存在于其他编译器或静态分析器中。
对于 clang,-Wunused-value -Werror
就可以了。第一个激活警告,第二个将其提升为错误。
就我个人而言,我赞成启用所有警告并明确禁用那些您有理由不遵守的警告,包括说明原因的文档。