1

For some reason I am getting the following error with the following code. It does not really make sense to me that std::string in one case has a c_str function and in another dosen't.

../Shader.hpp:29:19: error: request for member ‘c_str’ in ‘code’, which is of non-class type ‘std::__cxx11::string(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> > (*)()) {aka std::__cxx11::basic_string<char>(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> > (*)())}’
   loadString(code.c_str());


void loadFile(const char* fn)
{
    std::ifstream fin(fn);
    if(!fin.good())
        throw std::runtime_error("File could not be opened.");
    std::string code(std::istreambuf_iterator<char>(fin), std::istreambuf_iterator<char>());
    fin.close();
    loadString(code.c_str());
}

Then just to check I added another string.

void loadFile(const char* fn)
{
    std::ifstream fin(fn);
    if(!fin.good())
        throw std::runtime_error("File could not be opened.");
    std::string code(std::istreambuf_iterator<char>(fin), std::istreambuf_iterator<char>());
    fin.close();
    std::string test = "test";
    loadString(test.c_str());
}

Now this code compiles. I don't get why it works for one version but not the other.

chasep255
  • 11,745
  • 8
  • 58
  • 115
  • 3
    The symbol `code` is not a variable, it's a *function*. You declare it as a function which takes two `std::istreambuf_iterator` objects by value as arguments, and returns a `std::string`. Related to [the most vexing parse](https://en.wikipedia.org/wiki/Most_vexing_parse). Use either `std::string code{...}` (note use or curly-braces instead of parentheses), or use e.g. `std::string code = std::string(...)` – Some programmer dude Feb 07 '16 at 14:57
  • Thanks. I am surprised I have never come across that before. Wouldn't the compiler be able to tell for two reasons that it is a variable. One is that it is inside a function so you can't declare another function. Two is that std::istreambuf_iterator(fin) is a value not a data type? – chasep255 Feb 07 '16 at 15:10
  • 1
    You can have any type of declaration inside a function, including function prototypes, which leads to this problem. This is one of the reasons that uniform initialization using curly-braces `{}` was added in the C++11 standard. – Some programmer dude Feb 07 '16 at 15:13
  • `std::istreambuf_iterator(fin)` can be parsed as a declaration of a parameter named `fin` of type `std::istreambuf_iterator`, with redundant parentheses around `fin`. And because it can be, it must be. It's called vexing with good reason. – Alan Stokes Feb 07 '16 at 15:42

0 Answers0