C++__FILE__ 宏的类型是什么

发布于 2024-10-18 03:56:49 字数 440 浏览 1 评论 0原文

我正在尝试创建一个异常类。为此,我重载了 << 运算符。所以代码是这样的

class RunAndCheck
{
     opearator << (boost::any given)
     {

         //Here goes the value of the    "given"

     }
};

用法是这样的

RunAndCheck s;
s << file->open() << __FILE__ << __LINE__ ; 

所以问题是我想知道 FILE 的类型,那么只有我可以从 boost::any 中提取字符串。有人能激起你对此的好奇心吗?

I am trying to create an exception class. For this I overloaded the << operator. So the code is something like this

class RunAndCheck
{
     opearator << (boost::any given)
     {

         //Here goes the value of the    "given"

     }
};

The usage is like this

RunAndCheck s;
s << file->open() << __FILE__ << __LINE__ ; 

So the problem is that I want to know the type of the FILE, then only I can extract the string out of boost::any. Can anybody invoke your curiosity around this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

開玄 2024-10-25 03:56:49

__FILE__ 扩展为字符串文字,就像直接编写“/path/to/current/file.cpp”一样。字符串文字是不可修改的字符数组左值。

您想要模板 <<而不是使用 boost::any:

class RunAndCheck {
public:
    template<class T>
    RunAndCheck& operator<<(const T& value) {
        // ...
        return *this;
    }
};

或者您想为所有可接受的类型提供重载:

class RunAndCheck {
public:
    RunAndCheck& operator<<(const char* value) {
        // ...
        return *this;
    }
    RunAndCheck& operator<<(int value) {
        // ...
        return *this;
    }
};

__FILE__ expands into a string literal, just as if you had written "/path/to/current/file.cpp" directly. String literals are non-modifiable char array lvalues.

You want to template that << instead of using boost::any:

class RunAndCheck {
public:
    template<class T>
    RunAndCheck& operator<<(const T& value) {
        // ...
        return *this;
    }
};

Or you want to provide overloads for all the acceptable types:

class RunAndCheck {
public:
    RunAndCheck& operator<<(const char* value) {
        // ...
        return *this;
    }
    RunAndCheck& operator<<(int value) {
        // ...
        return *this;
    }
};
凡尘雨 2024-10-25 03:56:49

宏没有类型,它们只是预处理器所做的文本替换(没有类型检查)。 __FILE__ 放入的值的类型是常量 C 字符串。

Macros do not have types, they are just text replacements made by the preprocessor (without type checks). The type of the value dropped in by __FILE__ is a constant C string.

早茶月光 2024-10-25 03:56:49

__FILE__ 被替换为字符串文字,其类型为

const char[length_of_particular_string]

You should确实重新考虑您正在做的事情。 (意见也基于您的上一个问题。)

首先, boost::any 不适合这种用法(特别是因为字符串文字的类型在不同情况下会有所不同)。但即使不是因为技术困难,您也应该使用正常的函数重载。

更重要的是,您想要的功能似乎是接收一个布尔值,如果该值不为真,则抛出包含文件名和行号的错误。由于您始终需要所有 3 个组件(尽管根据您的描述,可以让它在不给出文件名的情况下抛出,或者让该类不执行任何有用的操作),因此采用这 3 个参数的函数更有意义。

此外,您现在可以将对此的调用包装在宏中,以便自动提供文件名和行号。

完整示例:

#include <stdexcept>
#include <sstream>
#include <iostream>

void check_result(bool result, const char* line, int line_number)
{
    if (!result) {
        //for example:
        std::stringstream ss;
        ss << line << ' ' << line_number;
        throw std::runtime_error(ss.str()); 
    } 
} 

#define CALL_AND_CHECK(expression) check_result((expression), __FILE__, __LINE__)

bool foobar(bool b) { return b; }

int main()
{
    try {
        CALL_AND_CHECK(foobar(true));
        CALL_AND_CHECK(foobar(false));
    } catch (const std::exception& e) {
        std::cout << e.what() << '\n';
    }
}

__FILE__ is replaced by a string literal, whose type is

const char[length_of_particular_string]

You should really reconsider what you are doing. (Opinion also based on your previous question.)

Firstly, boost::any is no good for such usage (in particular since the type of the string literal will be different in different cases). But even if not for the technical difficulties, you should use normal function overloading.

More importantly, it seems that the functionality that you want is to receive a boolean value and throw an error containing the file name and line number if the value is not true. Since you always require all 3 components (although according to your description it would be possible to have it throw without giving it the file name, or have the class do nothing useful), a function that takes those 3 arguments makes more sense.

Furthermore, you can now wrap calls to this in a macro, so that the file name and line number are automatically provided.

Full example:

#include <stdexcept>
#include <sstream>
#include <iostream>

void check_result(bool result, const char* line, int line_number)
{
    if (!result) {
        //for example:
        std::stringstream ss;
        ss << line << ' ' << line_number;
        throw std::runtime_error(ss.str()); 
    } 
} 

#define CALL_AND_CHECK(expression) check_result((expression), __FILE__, __LINE__)

bool foobar(bool b) { return b; }

int main()
{
    try {
        CALL_AND_CHECK(foobar(true));
        CALL_AND_CHECK(foobar(false));
    } catch (const std::exception& e) {
        std::cout << e.what() << '\n';
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文