为什么在下面的代码中,模板类型是否无法从最后一个参数自动推断出来,就像它在std::condition_variable::wait
中那样?
template< typename Predicate >
//requires Truth< Predicate >
class lock_monitor_guard
{
public:
lock_monitor_guard( std::mutex& mutex, std::condition_variable& monitor, Predicate predicate );
~lock_monitor_guard();
private:
std::unique_lock<std::mutex> lock;
std::condition_variable& monitor;
};
template< typename Predicate >
//requires Truth< Predicate >
lock_monitor_guard<Predicate>::lock_monitor_guard( std::mutex& mutex, std::condition_variable& monitor, Predicate predicate )
: lock( mutex ), monitor( monitor )
{
monitor.wait<Predicate>( lock, predicate );
}
template< typename Predicate >
//requires Truth< Predicate >
lock_monitor_guard<Predicate>::~lock_monitor_guard()
{
lock.unlock();
monitor.notify_one();
}
当我尝试构建像lock_monitor_guard guard( jobs_mutex, jobs_monitor, ([]()->bool{return true;}) );
这样的行时,我收到一条错误消息:use of class template 'lock_monitor_guard' requires template arguments
。但为什么 ?为什么它适用于STL std::condition_variable::wait
。谢谢你的帮助!
答案 0 :(得分:6)
类型的模板参数无法推断,期间。这是因为类型特化可以提供完全不同的成员集,因此在您知道类型的模板参数之前,您甚至不知道可用的构造函数。
这就是标准库具有辅助函数的原因,如std::make_pair
。在构造或引用std::pair
时,必须指定类型参数(std::pair<int, double>(1, 2.0)
),但在大多数情况下,可以在调用函数时推导出它们(std::make_pair(1, 2.0)
) 。 (请注意,std::condition_variable::wait
是一个函数,而不是一个类型。)
如果为lock_monitor_guard
类型实现移动构造函数,则可以创建一个与std::make_pair
精神相似的辅助函数,然后使用auto
复制初始化来提供演绎。 (请注意,您还必须调整析构函数,以解释this
移动构造函数使其内容“被盗”的可能性。)
template <typename Predicate>
lock_monitor_guard<Predicate> create_lock_monitor_guard(
std::mutex & mutex,
std::condition_variable & monitor,
Predicate && predicate)
{
return lock_monitor_guard<Predicate>(mutex, monitor, std::forward<Predicate>(predicate));
}
auto guard = create_lock_monitor_guard(
jobs_mutex,
jobs_monitor,
[] { return true; });
答案 1 :(得分:2)
您可以传递如下所示的类型。
template< typename Predicate >
//requires Truth< Predicate >
class lock_monitor_guard
{
public:
lock_monitor_guard( std::mutex& mutex, std::condition_variable& monitor, Predicate predicate );
};
auto pred = [] { return true; };
lock_monitor_guard<decltype(pred)> l(jobs_mutex, jobs_monitor, pred);
std::condition_variable::wait
是函数而不是类型因此会自动推导出类型。