CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    TR2 file library

    I've been reading up on an introduction to the TR2 file system library in Visual Studio 2012.

    I can't say I was very impressed by choice of using the '/' operator to concatonate file paths.
    It seemed to violate all of the good practices to do with operator overloads that I've read (and tended to agree with) over the years.

    Call me weird, but '/' doesn't immediately say 'concatonate' in my mind.

    Example from the blog:

    Code:
    auto startup_path = initial_path();    
    auto log_path = startup_path / path("logs/current"); 
    auto output_path = startup_path; 
    output_path /= "output";
    Surely '+' would have made much better sense, being that the concept of using it as a concatonation operator is not exaclty alien to any C++ coder. (Think std::string)

    What do you think?
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  2. #2
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: TR2 file library

    The reasoning behind that choice of operator apparently is that it resembles the most commonly used directory separation character. I'd probably have some difficulty getting used to it too, but I don't find it illogical.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  3. #3
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: TR2 file library

    Quote Originally Posted by JohnW@Wessex View Post
    I can't say I was very impressed by choice of using the '/' operator to concatonate file paths.
    It seemed to violate all of the good practices to do with operator overloads that I've read (and tended to agree with) over the years.

    Call me weird, but '/' doesn't immediately say 'concatonate' in my mind.
    The operator doesn't just concatenate. It adds a path separator and then concatenates. To me it makes as much sense as having the operator + for concatenation of std::string. It may take some getting used to in the beginning, but it's so much easier than named functions.
    Btw, it's a good thing that they didn't use + to append paths, because now you can write something like this:
    Code:
    path dir, subdir;
    std::string stem, suffix, extension;
    //...
    path fullPath = dir / subdir / (stem + suffix + extension);
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  4. #4
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: TR2 file library

    Quote Originally Posted by Eri523 View Post
    , but I don't find it illogical.
    I don't disagree that there is a logic behind choosing the '/' operator, it's just that you could come up with 'logical' uses for overloaded operators for all sorts of things. I did it in the past when I first found out about overloaded operators, but nowadays I stick to the rule of 'least surprise'. I avoid overloading operators where the meaning would stray too far from the canonical understanding.

    e.g.
    Seeing '+' implies that you are adding something to something else.
    In the case of numerics no one would have trouble understanding this, and in the case of strings, even a non-programmer would quite probably deduce this to mean concatonating a string to another.

    But in the case or '/' this goes a bit too far for my liking.

    1. It bears no relation to the canonical use of the '/' operator.
    2. It's logic works on the assumption that all file systems use (or will use in the future) the '/' character as a separator for folder or directory paths.
    3. It smacks a little too much of being a bit too 'clever'. (Hey, I've found a cool new use for an operator).


    Now, before anyone chips in, I know that the '<<' & '>>' operators already can be said to fall foul of (1) and (3), but they've been around practically from the beginning of C++ and we all know (and love?) them. But that's never been a good argument for overloading an operator.

    I have this opinion because in the distant past I've overloaded operators because I found a 'neat' new meaning for it in terms of some class. I could even have argued a good logical case for each one of them too. All I can say is that, after years of experience in writing (and reading) C++, all of those 'neat' ideas have been refactored out.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  5. #5
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: TR2 file library

    Quote Originally Posted by D_Drmmr View Post
    Btw, it's a good thing that they didn't use + to append paths, because now you can write something like this:
    Code:
    path dir, subdir;
    std::string stem, suffix, extension;
    //...
    path fullPath = dir / subdir / (stem + suffix + extension);
    I don't see that '+' would be a problem in this case.
    You are adding a path to a path and a string to a path. This would be surely be accomodated by overloads of the '+' operator.

    Code:
    std::path &operator + (const std::path& lhs, const std::path& rhs);
    
    std::path &operator + (const std::path& lhs, const std::string& rhs);
    
    std::path dir, subdir;
    std::string stem, suffix, extension;
    
    std::path fullPath = dir + subdir + (stem + suffix + extension);
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  6. #6
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: TR2 file library

    Quote Originally Posted by JohnW@Wessex View Post
    Seeing '+' implies that you are adding something to something else.
    In the case of numerics no one would have trouble understanding this, and in the case of strings, even a non-programmer would quite probably deduce this to mean concatonating a string to another.
    I don't agree with you here. I don't think the meaning of operator + on strings follows from analogy. By analogy I would expect "aa" + "bc" to equal "cd". However, that doesn't make sense and, in fact, concatenation is the only thing that does make sense when 'adding' strings. So, to me it is more convention than anything else.
    Quote Originally Posted by JohnW@Wessex View Post
    I don't see that '+' would be a problem in this case.
    You are adding a path to a path and a string to a path. This would be surely be accomodated by overloads of the '+' operator.
    But in that case the behavior would depend on the type of the arguments. I.e. if 'dir' and/or 'subdir' were std::string's rather than std:ath's, the result would be different. Also, in your code it is not clear anymore why the brackets are needed. So, IMO this would be very difficult to read.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  7. #7
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: TR2 file library

    Quote Originally Posted by D_Drmmr View Post
    , concatenation is the only thing that does make sense when 'adding' strings.
    But that's my point. When you look at the operator your first thought will be "how would the canonical understanding of this operator apply to this context". It just doesn't work for '/'.

    Also, in your code it is not clear anymore why the brackets are needed.
    The brackets would not infact be needed.

    Code:
    std::path fullPath = dir + subdir + stem + suffix + extension;
    
    path + path   => path (dir + subdir)
    path + string => path (+ stem)
    path + string => path (+ suffix)
    path + string => path (+ extension)
    No real difference from how std::complex works, for instance.

    Code:
    complex + complex => complex
    complex + numeric => complex

    So, IMO this would be very difficult to read.
    Well, we'll have to just disagree there as I find quite the opposite.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  8. #8
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: TR2 file library

    Quote Originally Posted by JohnW@Wessex
    But that's my point. When you look at the operator your first thought will be "how would the canonical understanding of this operator apply to this context". It just doesn't work for '/'.
    On one hand, I agree: if I look at (a / b), I think "division", not "path". On the other hand, I disagree: if I look at (a << b), I think "left shift", not "output to a stream", yet if I look at (std::cout << "hello world"), I think of "output to a stream". The use of << is canonical now in that context, but at some point it was not.

    As such, I can understand the motivation behind overloading operator/ for this context. The association is not strong, especially since other separators are also in use for paths from an OS point of view, but there is a link and given time, I could accept it as canonical.

    EDIT:
    Speaking of this, at some point, overloading operator+ to concatenate strings was not canonical either. Addition is commutative; string concatenation is not commutative. As such, a canonical understanding of operator+ shows that it is a bad choice for string concatenation... except that there is a link and it has seen such widespread use, and thus is canonical.
    Last edited by laserlight; January 25th, 2013 at 10:22 AM.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  9. #9
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: TR2 file library

    Quote Originally Posted by laserlight View Post
    ... except that there is a link and it has seen such widespread use, and thus is canonical.
    Whilst I agree that, in a couple of instances, there are operators who's meaning in certain contexts have become canonical (and with '+' for strings I don't think it was a particularly great mental leap to make), I don't see the advantage in introducing yet another one to the standard library.
    The concepts of concatonating paths and concatonating strings are so similar that I see no problem in using the same operator for each. It's the path of 'least surprise and misunderstanding'.

    I'm probably just whistling in the wind and it will get baked in to the standard and I'll just end up grumbling about it to anyone who'll listen like an old fart programmer.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  10. #10
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: TR2 file library

    Quote Originally Posted by JohnW@Wessex View Post
    The brackets would not infact be needed.

    Code:
    std::path fullPath = dir + subdir + stem + suffix + extension;
    
    path + path   => path (dir + subdir)
    path + string => path (+ stem)
    path + string => path (+ suffix)
    path + string => path (+ extension)
    I think they would be needed. Can't test it right now, but if I'm not mistaken, leaving out the brackets gives a different result.
    Code:
    std::path dir = "C:\\one", subdir = "two";
    std::string stem = "file_", suffix = "01", extension = ".txt";
    std::path fullPath1 = dir / subdir / (stem + suffix + extension);
    The value of fullPath1 is "C:\\one\\two\\file_01.txt".
    Contrary, if operator + was defined instead of operator / for paths.
    Code:
    std::path dir = "C:\\one", subdir = "two";
    std::string stem = "file_", suffix = "01", extension = ".txt";
    std::path fullPath2 = dir + subdir + stem + suffix + extension;
    the value of fullPath2 would be "C:\\one\\two\\file_\\01\\.txt".

    It looks like the Boost implementation overloads both operator / and operator +, but the latter just concatenates and the former adds a path separator and then concatenates. So, indeed with the Boost implementation the brackets are not needed, because both operators are overloaded with different semantics. That's exactly the point I was trying to make.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  11. #11
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: TR2 file library

    and why is "+" a more logical choice as concatenation operator than... any other operator out there ?
    That's only because by now you have gotten used to that notation from using languages that use that symbol. and I'll agree that probably most do use "+", but I wouldn't call it a "logical" choice, just a "convention" or "habit" at best, and not even a very good one at that.

    Visual basic and ada uses "&" to contatenate strings.
    Perl and PHP use "."
    Lua uses ".." to concatenate strings


    From pure math p.o.v. a+b does something entirely different for strings than for numerical values

    why is 4+5 equal to 9 where "4"+"5" is equal to "45"
    and why is 4+5 equal to 5+4 where "4"+"5" is not equal to "5"+"4"
    "Everyone" knows that + is associative, why isn't it for strings ? isn't that an indication that "+" is a bad operator for concatenation ?

    surely from a logic pov it would have been better to take a different operator because it obviously doesn't behave the same for numeric values as it does for strings.
    For paths... I can see some merit in "/" since that's what you put in between folders in a path. But yes, it's "weird" because you're not used to that notation. They could have used anything else than "+" and you'd have found it equally weird because you're used to seeing +.

  12. #12
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: TR2 file library

    Quote Originally Posted by OReubens View Post
    Visual basic and ada uses "&" to contatenate strings.
    Perl and PHP use "."
    Lua uses ".." to concatenate strings
    What other languages use is of no concern to me. It's what the 'conventions' are for C++ that matter.
    why is 4+5 equal to 9 where "4"+"5" is equal to "45"
    and why is 4+5 equal to 5+4 where "4"+"5" is not equal to "5"+"4"
    "Everyone" knows that + is associative, why isn't it for strings ? isn't that an indication that "+" is a bad operator for concatenation ?
    Maybe, maybe not, but STL strings have been around for a long long time and the slight difference in meaning is unlikely to confuse anyone, even a newbie.
    They could have used anything else than "+" and you'd have found it equally weird because you're used to seeing +.
    Quite probably, but I still see don't reason to be adding yet another one. Just for the sake of being able to use a 'cool' syntax. What next? I think it sets a bad precedent and a bad example to newbie coders.
    This sort of overloading was the sort of stuff I did before I realised that you should code 'smart' not 'clever'.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  13. #13
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: TR2 file library

    Quote Originally Posted by OReubens
    why is 4+5 equal to 9 where "4"+"5" is equal to "45"
    and why is 4+5 equal to 5+4 where "4"+"5" is not equal to "5"+"4"
    "Everyone" knows that + is associative, why isn't it for strings ?
    Actually, operator+ is associative for std::string objects; operator+ is not commutative for std::string objects, but it is for real numbers in mathematics.

    Quote Originally Posted by JohnW@Wessex
    Quite probably, but I still see don't reason to be adding yet another one. Just for the sake of being able to use a 'cool' syntax.
    D_Drmmr pointed out that it is not just "cool syntax", but semantic difference of string concatenation versus path separation.

    Quote Originally Posted by JohnW@Wessex
    What next?
    Boost.Spirit?
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  14. #14
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: TR2 file library

    Quote Originally Posted by laserlight View Post
    D_Drmmr pointed out that it is not just "cool syntax", but semantic difference of string concatenation versus path separation.
    Well, actually, I'd much prefer a system were adding a path or string to a path would add the path separator, unless the string was already prefixed/postfixed with the separators.

    If you want to create a string that is not a path, then just concatonate strings! This would ofcourse require the inclusion of the brackets in the earlier example, but I don't see it as any big deal.

    Code:
    std::path path1("dir1");
    std::path path2("dir2");
    std::path path3("dir3");
    
    std::string string1("myfile");
    std::string string2(".txt");
    
    std::path path4 = path1 + path2 + path3 + (string1 + string2);
    
    or
    
    std::string filename(string1 + string2);
    std::path path4 = path1 + path2 + path3 + filename;
    
    => dir1/dir2/dir3/myfile.txt
    I haven't seen any argument yet that convinces me that using the '/' operator is anything other than someone being 'clever' with operator overloading just to get a 'cool' syntax.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured