【问题标题】:C++ multithreading and passing templated arguments <typename T>(T arg)C++ 多线程和传递模板化参数 <typename T>(T arg)
【发布时间】:2021-08-05 11:05:49
【问题描述】:

我有这段代码,没有任何问题:

void function_exit(dispatcher& d) { /* .. */ }
// ...
std::thread th(function_exit, std::ref(main_disp));
th.detach();

现在我尝试创建另一个包含 std::thread 的类,它会在编译时产生错误

thread_control mtc;
mtc.create<dispatcher&>(function_exit, main_disp);

这里是创建函数:(请阅读注释文本以描述问题)

template<typename Arg>
inline bool thread_control::create(void(*function)(Arg), Arg value)
{
    bool ok = false;
    if (created == false)
    {
        created = true;
        if (typeid(Arg).hash_code() == typeid(void).hash_code())
        {
            // this produce thread(50,5): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&) noexcept(<expr>)'
            // type_traits(1583): message : see declaration of 'std::invoke'
            // thread(50,5): message : With the following template arguments:
            // thread(50,5): message : '_Callable=void (__cdecl *)(Arg)'
            m_thread = std::thread(function);
        }
        else
        {
            if (std::is_reference<Arg>::value)
            {
                // if only this function is used, program is compiled without errors and runs without problem.
                // (when i comment functions which are problematic and this function is uncomented)
                m_thread = std::thread(function, std::ref(value)); 
            }
            else
            {
                // this function produce this errors:
                // 2>...\Visual Studio 2019\VC\Tools\MSVC\14.28.29910\include\thread(65): message : see reference to function template instantiation 'unsigned int (__stdcall *std::thread::_Get_invoke<_Tuple,0,1>(std::integer_sequence<size_t,0,1>) noexcept)(void *)' being compiled
                // thread(50,5): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Ty1 &&,_Types2 &&...) noexcept(<expr>)'
                // type_traits(1589): message : see declaration of 'std::invoke'
                // thread(50,5): message : With the following template arguments:
                // thread(50,5): message : '_Callable=void (__cdecl *)(Arg)'
                // thread(50,5): message : '_Ty1=dispatcher'
                // thread(50,5): message : '_Types2={}'
                // thread(50,5): error C2780: 'unknown-type std::invoke(_Callable &&) noexcept(<expr>)': expects 1 arguments - 2 provided
                // type_traits(1583): message : see declaration of 'std::invoke'
                m_thread = std::thread(function, value);
            }
        }
        ok = true;
    }
    return ok;
}

我的m_thread = std::thread(...); 函数抛出这些编译错误有什么问题?还是我做错了什么?

【问题讨论】:

    标签: c++ multithreading templates arguments


    【解决方案1】:
     if (std::is_reference<Arg>::value)
    

    对于给定的Arg,当然,这将评估为truefalse

    但是两者当这个条件为真时执行的代码,和当这个条件为假时执行的代码必须是有效的C++.

     m_thread = std::thread(function, value);
    

    如果 Arg 是一个引用,那么这不是有效的 C++。即使if 条件将评估为true,并且这不会被执行,这个仍然必须是有效的C++

    这里可以使用两种基本方法。

    1. 在 C++17 及更高版本中使用 if constexpr

    2. 使用 C++14 及更早版本,您将需要重写整个事物以使用特化(整个模板函数,或将相关逻辑移动到模板类中并特化它们)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-05
      • 2021-10-29
      • 2011-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多