C ++奇怪的模板问题

时间:2013-12-09 19:38:45

标签: c++ templates

我有一个嵌套类型的类,以便允许类模板共享静态互斥锁:

template<int ID = 0>
class single_lockable
{
    static std::mutex M_mu;
protected:
    class single_lock :public std::lock_guard<std::mutex>
    {
    public:
        single_lock()
            :std::lock_guard<std::mutex>(M_mu)
        {
        }
    };
};

template<int ID>
std::mutex single_lockable<ID>::M_mu;

一个流包装器,以保证线程安全:

template<ostream& stream, int ID = 0>
class thread_safe_stream_wrapper :public single_lockable<ID>
{
    ...
    typedef typename single_lockable<ID>::single_lock single_lock;

public:
    ...
    thread_safe_stream_wrapper<stream,ID>& operator<<(const std::string& Arg)
    {
        M_stringbuilder << Arg;
        if (Arg[Arg.length() - 1] == '\n')
        {
            single_lock lock();
            stream << M_stringbuilder.str();
            M_stringbuilder.str(std::string());
        }
        return *this;
    }
};

thread_safe_stream_wrapper<std::cout> thread_safe_cout;
thread_safe_stream_wrapper<std::cerr> thread_safe_cerr;

然而,我在single_lock lock();上遇到了麻烦:

GCC: error: default argument for template parameter for class enclosing 'thread_safe_stream_wrapper<stream, ID>::single_lock lock()'
MSVC: warning C4930: 'single_lockable<0>::single_lock lock(void)': prototyped function not called (was a variable definition intended?)

如果我改成它,它运作良好:

single_lock lock;

你能解释一下为什么会这样吗?如果A是一个类,我认为A a;A a();之间没有任何区别。我错过了一些重要的语法点吗?感谢。

2 个答案:

答案 0 :(得分:1)

  

如果A a;是一个类,我认为A a();A之间没有任何区别

你错了。

  

我错过了一些重要的语法点吗?

single_lock lock()是一个函数声明。是的,甚至在功能体内!

确实,错误消息在其文本中暗示了这一点:

  

未调用prototyped函数(是一个变量定义?)

是的,它是!写single_lock lock;

这与the most vexing parse有关,但并不复杂。

答案 1 :(得分:1)

而不是

single_lock lock();

使用

single_lock lock;

或奖励C ++ 11-ness

auto lock = single_lock{};

这三个是等价的,第一个形式很容易被解释为一个函数声明(“最令人烦恼的解析” - 如果解析器将其解释为函数说明,它将首先超越其他规则)。< / p>

见这里:http://herbsutter.com/2013/05/09/gotw-1-solution/