3

プロジェクトの開発中C++にデバッグが頻繁に必要になり、通常はこのマクロを使用してデバッグを行います

#define DBUG(a) {std::cout << #a << " : " << a << std::endl;};

しかし、多くの場合、私はこのようなことをする必要があります

int a;
std :: string b;
double c;
...
...
DBG(a); DBG(b); DBG(c);

DBUG(a, b, c)しかし、理想的には、このようなことを達成するために、単に書くかDBG(a, b, c, d, e)、より多くの変数を使用することが可能かもしれません. いくつかの調査の後、これはメタプログラミングまたはより具体的にはコード生成の問題のように見えましたが、これらの分野に関する私の限られた知識のために、それを行う方法を見つけることができませんでした.

可能であれば、Boost やその他の外部ライブラリを使用せずにこれを解決したいと考えています。C++98それが不可能な場合は、C++11.

4

4 に答える 4

7

特定の数の引数に制限するのは好きではありません。名前を静的にデコードする優れたアプローチが見つからなかったため、名前はコンマ区切りの文字列としてまとめられ、実行時にデコードされます。全体として、それは少し重すぎるかもしれませんが、少なくとも、要求されたとおりに機能し、引数の数に制限はありません (つまり、コンパイラの制限以外):

#include <iostream>
#include <sstream>
#include <iterator>
#include <algorithm>
#include <tuple>
#include <vector>
#include <type_traits>
#include <stdlib.h>

template <int I, int S, typename... V>
typename std::enable_if<I == S>::type
debug_var(std::vector<std::string> const&, std::tuple<V...> const&)
{
}

template <int I, int S, typename... V>
typename std::enable_if<I != S>::type
debug_var(std::vector<std::string> const& n, std::tuple<V...> const& v)
{
    std::cout << n[I] << '=' << std::get<I>(v) << ' ';
    debug_var<I + 1, S>(n, v);
}

template <typename... V>
void debug(std::vector<std::string> const& n, std::tuple<V...> const& v)
{
    debug_var<0, sizeof...(V)>(n, v);
    std::cout << '\n' << std::flush;
}

std::vector<std::string> debug_names(char const* names)
{
    std::vector<std::string> result;
    std::istringstream in(names);
    for (std::string name; std::getline(in >> std::ws, name, ','); ) {
        result.push_back(name);
    }
    return result;
}

#define DEBUG(...) debug(debug_names(#__VA_ARGS__), std::tie(__VA_ARGS__));

int main()
{
    int a=1, b=2;
    DEBUG(a, b);
    DEBUG();
}

このコードは、C++ の 2011 リビジョンで導入されたいくつかの機能を使用しています。

于 2013-10-01T04:48:36.147 に答える
0

DBUG(a)次の方法で独自のものを使用できます

DBUG(a << " " << b << " " << c);

于 2013-10-02T15:46:30.667 に答える
-1

古き良き C++11 可変個引数テンプレートを使用するのはどうですか?

#include <iostream>
#include <sstream>
#include <string>


template <typename T>
std::string make_string(const T& t)
{
    std::ostringstream oss;
    oss << t;
    return oss.str();
}

template <typename Thead, typename ... Ttail>
std::string make_string(const Thead& head, const Ttail& ... tail)
{
    return make_string(head) + make_string(tail...);
}

void debug(const std::string& msg)
{
    std::cout << "DEBUG: " << msg << std::endl;
}

void debug(void)
{
    std::cout << "DEBUG!" << std::endl;
}

template <typename ... Targs>
void debug(const Targs& ... args)
{
    debug(make_string(args...));
}



int main(void)
{
    int z;
    debug("We're gonna crash: ", &z, "!");
    debug();
    debug(3.14);
}
于 2013-10-01T04:28:08.267 に答える