C++ __FILE__宏的类型是什么

pra*_*ran 12 c++ macros logic visual-c++

我正在尝试创建一个异常类.为此,我重载了<<操作员.所以代码是这样的

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

         //Here goes the value of the    "given"

     }
};
Run Code Online (Sandbox Code Playgroud)

用法是这样的

RunAndCheck s;
s << file->open() << __FILE__ << __LINE__ ; 
Run Code Online (Sandbox Code Playgroud)

所以问题是我想知道FILE的类型,然后我只能从中提取字符串boost::any.任何人都能引起你的好奇心吗?

Tho*_*son 11

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

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

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

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

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


jde*_*aan 8

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

  • 他的意思是`const char*`. (4认同)
  • @Stephane Rolland:const char*不正确,尽管你可以从字符串文字中得到它. (3认同)
  • 说"宏没有类型"并不是很有用.宏扩展到的值具有类型,就像所有值一样. (2认同)

vis*_*tor 5

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

const char[length_of_particular_string]
Run Code Online (Sandbox Code Playgroud)

你真的应该重新考虑一下你在做什么。(意见也基于您之前的问题。)

首先,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';
    }
}
Run Code Online (Sandbox Code Playgroud)