4

I want to supply some inline convenience functions using std::string in my header alongside with the library functions which use const char *, but I do not want to include <string>. I want to check with #ifdef if <string> is included and provide the convenience functions if this is the case.

Question: Are the names of header guards in STL headers the same for all STL implementations? In Visual Studio 2010, the header guard of <string> is _STRING_.

Evg
  • 25,259
  • 5
  • 41
  • 83
Fabian
  • 4,001
  • 4
  • 28
  • 59
  • 5
    Generally having includes have different effects based on order will confuse people. – Fire Lancer Jan 07 '20 at 09:54
  • In C++17 you could use [`std::string_view`](https://en.cppreference.com/mwiki/index.php?search=string_view). It is much lighter to include than `std::string` and provides a read-only view into either a `std::string` or a `const char*`. Of course this only works if you don't have to mutate the string. – sv90 Jan 07 '20 at 10:17
  • 2
    The standard requires **only** that the headers work correctly if included multiple times. Header guards are the most common mechanism, but they are not required. – Pete Becker Jan 07 '20 at 15:02

2 Answers2

16

This is a BAD IDEA™.

Generally, you cannot and shouldn't rely on an implementation detail of a compiler / library1. On top on that, as stated by Fire Lancer in the comments, "having includes have different effects based on order will confuse people" and adds to the wtf/line of your library.

What you could (should?) do is document a macro for the user to define in order to enable your std::string functions:

#ifdef MY_LIBRARY_ENABLE_STRING_FUNCTIONS
void print(std::string message);
#endif // MY_LIBRARY_ENABLE_STRING_FUNCTIONS

If the user wants them, they'll have to:

#define MY_LIBRARY_ENABLE_STRING_FUNCTIONS
#include <my_library>

1) C++17 has the __has_include(<filename>) macro (credit to acraig5075 for learning this to me) which doesn't help as it returns whether an include is available and not if it has been included.

YSC
  • 38,212
  • 9
  • 96
  • 149
  • Thank you for the valuable suggestions. Despite I changed my mind about doing what I intended, I am still curous if the header guard names in STL are standardized. Do you have any information on this? – Fabian Jan 07 '20 at 10:30
  • @Fabian No, they are not. They could use `#pragma once` or any builtin compiler magic if their developer wanted. They could even disobey the One Definition Rule, after all don't forget that the Standard Library isn't properly written in C++ and the C++ Standard doesn't _fully_ apply to it. – YSC Jan 07 '20 at 10:32
3

The most reliable way to check would probably be using technique.

That being said, DON'T DO THIS, everything screams anti-pattern when you want to differentiate on whether a header has been included or not, or the order of includes.

YSC
  • 38,212
  • 9
  • 96
  • 149
darune
  • 10,480
  • 2
  • 24
  • 62
  • 1
    It’s very hard to SFINAE on the absence of a declaration entirely; you can’t recover from non-dependent lookup failure. – Davis Herring Aug 11 '21 at 19:19