c++ - 为什么在构造字符串时 `std::istreambuf_iterator<char>`被视为函数声明?

标签 c++ parameters expression ambiguity function-declaration

许多程序员可能会混淆以下代码:

int main() {
  std::ifstream ifs("filename", std::ios::binary);
  std::string content((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
  //                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
  ...
}

我想清楚地理解此代码,所以问题是:
  • 为什么将std::istreambuf_iterator<char>(ifs)括在()中?
  • 如果在此处删除括号,如何确定此代码?和
  • 如果不删除方括号,如何确定代码?

  • 谢谢你的帮助。

    最佳答案

    在声明中,声明符可以放在括号中。

    考虑以下函数声明

    void f( int ( x ), int ( y ) );
    

    该声明声明一个带有两个类型为int的参数的函数。

    在声明中,可以省略标识符的名称。

    所以你可以写
    void f( int (), int () );
    

    该声明反过来声明一个函数,该函数接受函数类型为int()的两个参数。

    所以这个建筑
    std::string content(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>());
    

    可以被编译器视为函数的声明,该函数的返回类型为std::string,其第一个参数为std::istreambuf_iterator<char>类型,标识符为ifs,第二个参数为函数类型istreambuf_iterator<char>()

    为了将声明与表达式区分开来,可以使用括号之类的
    std::string content( ( std::istreambuf_iterator<char>(ifs) ), std::istreambuf_iterator<char>());
    

    或大括号
    std::string content(std::istreambuf_iterator<char>{ ifs }, std::istreambuf_iterator<char>());
    

    这是一个演示程序,该程序演示如何在参数声明中查找声明符。
    #include <iostream>
    
    void f( int ( x ), int ( y ) )
    {
        std::cout << "x = " << x << ", y = " << y << '\n';
    }
    
    void f( int(), int() );
    
    void f( int g(), int h() )
    {
        std::cout << g() + h() << '\n';
    }    
    
    int g() { return 100; }
    
    int main()
    {
        f( 10, 20 );    
    
        f( g, g );
    }
    

    程序输出为
    x = 10, y = 20
    200
    

    至于在注释中出现的有关函数类型参数声明的问题,则例如C函数qsort使用这样的参数来指定数组的两个元素之间的关系。
    void qsort(void *base, size_t nmemb, size_t size,
    int compar(const void *, const void *));
    

    另一个示例是将函数类型用作类模板std::function的模板参数。

    关于c++ - 为什么在构造字符串时 `std::istreambuf_iterator<char>`被视为函数声明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60336855/

    相关文章:

    mysql - .Net 与 MySQL : ignore parameters in commandtext

    c++ - 这个带 mustache 的笑脸是什么表情 : "<:]{%>"?

    java - Maven 表达式解决问题

    sql-server - 使用参数或变量在 SSIS 中设置连接超时?

    c++ - FreeRTOS任务不应返回-ESP32

    c++ - 从文本文件输入获取char C++

    c++ - 为什么在删除派生类对象时调用基类析构函数(虚拟)?

    c++ - 如何用 C++ 中的控制台替换 ​​txt 文件中的一行?

    java - 接口(interface)和参数问题

    C++将用户输入传递给变量,传递给函数的参数