模板参数无效,需要输入

问题描述 投票:0回答:1

给出以下片段

#include <stdexcept>
#include <vector>
#include <iostream>
#include <ostream>
#include <sstream>

namespace tools {
    namespace error {

        template<typename Base>
        struct wallet_error_base : public Base {
            const std::string &location() const { return m_loc; }

            std::string to_string() const {
                std::ostringstream ss;
                ss << m_loc << ':' << typeid(*this).name() << ": " << Base::what();
                return ss.str();
            }

        protected:
            wallet_error_base(std::string &&loc, const std::string &message)
                    : Base(message), m_loc(loc) {
            }

        private:
            std::string m_loc;
        };

        typedef wallet_error_base<std::logic_error> wallet_logic_error;

        struct wallet_rpc_error : public wallet_logic_error {
            const std::string &request() const { return m_request; }

            std::string to_string() const {
                std::ostringstream ss;
                ss << wallet_logic_error::to_string() << ", request = " << m_request;
                return ss.str();
            }

        protected:
            explicit wallet_rpc_error(std::string &&loc, const std::string &message, const std::string &request)
                    : wallet_logic_error(std::move(loc), message), m_request(request) {
            }

        private:
            std::string m_request;
        };

        struct wallet_generic_rpc_error : public wallet_rpc_error {
            explicit wallet_generic_rpc_error(std::string &&loc, const std::string &request, const std::string &status)
                    : wallet_rpc_error(std::move(loc), std::string("error in ") + request + " RPC: " + status, request),
                      m_status(status) {
            }

            const std::string &status() const { return m_status; }

        private:
            const std::string m_status;
        };

        // Base case for the variadic template recursion
        template<typename TException>
        void throw_wallet_ex(std::string&& loc) {
            TException e(std::move(loc));
            std::cout << e.to_string();
            throw e;
        }

        // Recursive variadic template function to accept a variable number of string arguments
        template<typename TException, typename... Args>
        void throw_wallet_ex(std::string&& loc, const Args& ... args) {
            TException e(std::move(loc), args...);
            std::cout << e.to_string();
            throw e;
        }
    }
}

#define THROW_ON_RPC_RESPONSE_ERROR(r, error, res, method, ...) \
  do { \
    std::cout << "Doing work here"; \
    THROW_WALLET_EXCEPTION_IF(res.status != "ok", ## __VA_ARGS__); \
  } while(0)

#define THROW_ON_RPC_RESPONSE_ERROR_GENERIC(r, err, res, method) \
  THROW_ON_RPC_RESPONSE_ERROR(r, err, res, method, tools::error::wallet_generic_rpc_error, method, res.status)

#define STRINGIZE_DETAIL(x) #x
#define STRINGIZE(x) STRINGIZE_DETAIL(x)

#define THROW_WALLET_EXCEPTION_IF(cond, err_type, ...)                                                      \
  if (cond)                                                                                                 \
  {                                                                                                         \
    std::cerr << #cond << ". THROW EXCEPTION: " << #err_type;                                              \
    tools::error::throw_wallet_ex<err_type>(std::string(__FILE__ ":" STRINGIZE(__LINE__)), ## __VA_ARGS__); \
  }

  struct result {
    result(const std::string& status) : status(status) {

    }
    std::string status;
};

int main() {
    result res("ok");
    THROW_ON_RPC_RESPONSE_ERROR_GENERIC(true, {}, res, "rpc_access_submit_nonce");
    return 0;
}

我收到错误

ERROR: C:/users/katso/documents/github/denarii/src/BUILD:1161:10: Compiling src/example_of_error.cpp failed: (Exit 2): cl.exe failed:
error executing CppCompile command (from target //src:example_of_error) C:\Program Files (x86)\Microsoft Visual Studio\2022\Community\
VC\Tools\MSVC\14.30.30705\bin\HostX64\x64\cl.exe ... (remaining 1 argument skipped)
cl : Command line warning D9002 : ignoring unknown option '-O3'
cl : Command line warning D9002 : ignoring unknown option '-std=c++17'
cl : Command line warning D9002 : ignoring unknown option '-std=c++17'
src/example_of_error.cpp(109): error C2672: 'tools::error::throw_wallet_ex': no matching overloaded function found
src/example_of_error.cpp(109): error C2974: 'tools::error::throw_wallet_ex': invalid template argument for 'Args', type expected
src/example_of_error.cpp(74): note: see declaration of 'tools::error::throw_wallet_ex'
src/example_of_error.cpp(109): error C2977: 'tools::error::throw_wallet_ex': too many template arguments
src/example_of_error.cpp(66): note: see declaration of 'tools::error::throw_wallet_ex'
Target //src:example_of_error failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 5.192s, Critical Path: 0.38s
INFO: 2 processes: 2 internal.
ERROR: Build did NOT complete successfully

这是 Windows 10,带有来自 msys2 的 gcc 13.2.0,使用 bazel 7.0

当我将鼠标悬停在对“THROW_ON_RPC_RESPONSE_ERROR_GENERIC”的调用上时,Clion 向我展示了这一点

do {
    std::cout << "Doing work here";
    if (res.status != "ok") {
        std::cerr << "res.status != \"ok\"" << ". THROW EXCEPTION: " << "tools::error::wallet_generic_rpc_error";
        tools::error::throw_wallet_ex<tools::error::wallet_generic_rpc_error>(std::string("_file_name_" ":" "106"),
                                                                              "rpc_access_submit_nonce", res.status);
    };
}
while (0)

据我所知,使用 3 个字符串参数调用可变参数模板函数应该可以工作。

c++ templates macros bazel
1个回答
0
投票

正如有些人指出的那样,我在这里无意中使用了

MSVC

这是由于:https://github.com/bazelbuild/bazel/issues/20492

© www.soinside.com 2019 - 2024. All rights reserved.