简体   繁体   中英

why is `std::istreambuf_iterator<char>` regard as function declaration when constrcuting a string?

Many coders may be confused this code:

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

I would like to understand this code clearly, so the question is:

  1. Why is std::istreambuf_iterator<char>(ifs) enclosed in ( , ) ?

  2. How to determinate this code if remove the brackets here? and

  3. How to determinate the code if we don't remove the brackets?

Thanks for your help.

In declarations declarators may be enclosed in parentheses.

Consider the following function declaration

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

This declaration declares a function with two parameters of the type int.

In a declaration names of identifiers may be omitted.

So you may write

void f( int (), int () );

This declaration in turn declares a function that accepts two parameters of the function type int() .

So this construction

std::string content(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>());

can be considered by the compiler as a declaration of a function that has the return type std::string and with the first parameter of the type std::istreambuf_iterator<char> and the identifier ifs and the second parameter with the function type istreambuf_iterator<char>() .

To distinguish a declaration from an expression there are used either parentheses like

std::string content( ( std::istreambuf_iterator<char>(ifs) ), std::istreambuf_iterator<char>());

or braces

std::string content(std::istreambuf_iterator<char>{ ifs }, std::istreambuf_iterator<char>());

Here is a demonstration program that shows how can look declarators in parameter declarations.

#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 );
}

The program output is

x = 10, y = 20
200

As for the question appeared in a comment about declaration of a parameter of a function type then for example the C function qsort uses such a parameter that specifiers the relation between two elements of an array.

void qsort(void *base, size_t nmemb, size_t size,
int compar(const void *, const void *));

Another example is of using a function type as a template argument for a class template std::function .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM