模板化函数的 CTAD

问题描述

我正在编写一个日志类,它使用源位置作为默认参数。

我想要一个类似 printf 的函数调用,我希望使用 CTAD 应该可以实现,但在这种情况下,它用于模板化函数而不是模板化类,所以很明显 vlog 不是类型(它是一个函数)因此错误。

不太确定我哪里出错了或者这是否真的可能??

log 采用基本的字符串视图并且工作正常。

vlog 是采用 printf 样式参数列表的“聪明”位,即 const char* 然后是不同类型的可变参数。我已尝试包含尽可能多的代码,以防有更好的方法!

C++17 并提前致谢。

#include <chrono>
#include <experimental/source_location>
#include <mutex>
#include <string_view>
#include <string>
#include <iostream>

namespace LOGGING
{


class Logging
{
    using Ms                = std::chrono::milliseconds;                ///< typename alias
    using source_location   = std::experimental::source_location;       ///< typename alias

    constexpr static Ms defalt_mutex_wait{100};
    
public:
    static bool log(const std::string_view& msg,const source_location& location = source_location::current())
    {
        if (mutx.try_lock_for(defalt_mutex_wait))
        {
            std::cout << location.file_name() << "[" << \
                location.line() << ":" << \
                location.function_name() << "]: " << \
                msg;
            std::cout << std::endl; // flush
            
            mutx.unlock();
            return true;
        }
        return false;
    }

    template <typename... T>
    static bool vlog(const char*&& fmt,T&&... vars,const source_location& location = source_location::current())
    {
        if (mutx.try_lock_for(defalt_mutex_wait))
        {
            char buf[100]{};
            snprintf(buf,sizeof(buf),fmt,vars...);
            std::cout << location.file_name() << "[" << \
                location.line() << ":" << \
                location.function_name() << "]: " << \
                buf;
            std::cout << std::endl; // flush
            
            mutx.unlock();
            return true;
        }
        return false;
    }

    template <typename... T>
    vlog(const char*,T&&...) -> vlog<T...>;

    template<class Rep,class Period>
    [[nodiscard]] static bool lock(std::unique_lock<std::recursive_timed_mutex>& lock,const std::chrono::duration<Rep,Period>& timeout_duration = Ms(100))
    {
        if (mutx.try_lock_for(timeout_duration))
        {
            lock = std::move(std::unique_lock<std::recursive_timed_mutex>(mutx));
            mutx.unlock();
            return true;
        }
        return false;
    }

    static bool lock(std::unique_lock<std::recursive_timed_mutex>& lock)
    {
        lock = std::move(std::unique_lock<std::recursive_timed_mutex>(mutx));
        return true;
    }

private:
    Ms              instance_mutex_wait{defalt_mutex_wait};

public:
    Logging(void) noexcept = default;

private:
    static std::recursive_timed_mutex mutx;
};

inline std::recursive_timed_mutex Logging::mutx{};

inline Logging LOG;

} // namespace LOGGING



int main()
{
    using namespace LOGGING;

    LOG.log("Hello world!");
    LOG.vlog<int>("Value is %d",42);
    LOG.vlog("Value is %d",42); // HERE

    return 0;
}
<source>:58:34: error: 'vlog<T ...>' does not name a type
   58 |     vlog(const char*,T&&...) -> vlog<T...>;
      |                                  ^~~~~~~~~~
<source>:58:44: error: expected constructor,destructor,or type conversion before ';' token
   58 |     vlog(const char*,T&&...) -> vlog<T...>;

Godbolt link

任何感兴趣的人的上下文;它适用于多线程和多核嵌入式系统(ESP32),主要需要防止不同的线程日志消息交错。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...