C++20 - import vs. #include

I made a somewhat off-hand comment here, http://www.cplusplus.com/forum/general/282156/, about importing C headers as modules, something the references I am studying from indicate shouldn't happen/is not recommended. With VS in my experience that isn't completely true. I haven't found any instances yet, haven't really checked, but I am sure there might be headers that can't.

Importing <cstdio> or <Windows.h> for instance works. *shrug*

Plus the new C++20 library headers can still be #included as older C++ library headers

My question is simply: as programmers move forward and write new code will they use import more and more, or still #include?

I personally will do import more than #include, any older code libraries I wrote that uses headers/cpp format I will update to modules.

I am a bit surprised just how easy modularizing older code is.
Last edited on
have you tried a header only library?
I have converted my custom header-only libraries to implementation files. .hpp to .cppm, keeping both files for use.

My custom libraries are pre-C++20, mostly header-only files. Lots of inlining with custom namespaces.

Here's one of my header-only libraries:
menu_toolkit.hpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// "easy" menu utility

#ifndef MENU_TOOLKIT
#define MENU_TOOLKIT

#include <iostream>
#include <string>
#include <vector>
#include <sstream>

namespace MTK // (Menu Toolkit)
{
   inline void DisplayMenu(const std::vector<std::string>& stringArray)
   {
      std::cout << stringArray[0] << '\n';

      for (size_t i { 1 }; i < stringArray.size(); i++)
      {
         std::cout << " " << i << ") " << stringArray[i] << '\n';
      }
      std::cout << ": ";
   }

   inline unsigned short Menu(const std::vector<std::string>& stringArray)
   {
      unsigned short response { };
      size_t         size     { stringArray.size() - 1 };
      std::string    input    { };

      while (response < 1 || response > size)
      {
         DisplayMenu(stringArray);

         while (std::getline(std::cin, input))
         {
            std::istringstream is { input };

            if ((is >> response) && !(is >> input)) // re-using 'input' to test for extra stuff after the number
            {
               break; // done, we got what we wanted
            }
            std::cerr << "\n** INVALID CHOICE! **\n\n";
            DisplayMenu(stringArray);
         }

         if (response < 1 || response > size)
         {
            std::cerr << "\n** INVALID CHOICE! **\n\n";
         }
      }
      return response;
   }
}

#endif 

"Converted" to an implementation file, header_toolkit.cppm:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// "easy" menu utility

// modularized for C++20!

export module menu_toolkit;

import <iostream>;
import <string>;
import <vector>;
import <sstream>;

namespace MTK // (Menu Tool Kit)
{
   export void DisplayMenu(const std::vector<std::string>& stringArray)
   {
      std::cout << stringArray[0] << '\n';

      for (size_t i { 1 }; i < stringArray.size(); i++)
      {
         std::cout << " " << i << ") " << stringArray[i] << '\n';
      }
      std::cout << ": ";
   }

   export unsigned short Menu(const std::vector<std::string>& stringArray)
   {
      unsigned short response { };
      size_t         size { stringArray.size() - 1 };
      std::string    input { };

      while (response < 1 || response > size)
      {
         DisplayMenu(stringArray);

         while (std::getline(std::cin, input))
         {
            std::istringstream is { input };

            if ((is >> response) && !(is >> input)) // re-using 'input' to test for extra stuff after the number
            {
               break; // done, we got what we wanted
            }
            std::cerr << "\n** INVALID CHOICE! **\n";
            DisplayMenu(stringArray);
         }

         if (response < 1 || response > size)
         {
            std::cerr << "\n** INVALID CHOICE! **\n";
         }
      }
      return response;
   }
}

I have tested both the header and implementation, and either method works as expected in Visual Studio, no glitches or wrong output.

I'm almost positive I could move exporting from the individual functions up to the namespace declaration, I haven't tried that yet. Later I should do that with Menu Toolkit 2.0 after I do more studying on modules.

MTK 1.0 works, though. :)

I am not fond of the .ixx implementation file extension VS wants to use, all the MS documentation with custom modules use that. .cppm works in VS. The C++20 books I am learning from have .cppm for the implementation files.
In VS there's also import std.core; which brings in most of 'standard' c++ stuff.
https://docs.microsoft.com/en-us/cpp/cpp/modules-cpp?view=msvc-170

Re file extension.

See https://devblogs.microsoft.com/cppblog/standard-c20-modules-support-with-msvc-in-visual-studio-2019-version-16-8/

It says 'The files with .ixx or .cppm extensions are considered “Module interface” source.'

I know it is "there," but I kinda want to avoid import std.core; since that is NOT part of the C++20 standard.

All the MS modules documentation I read before C++20 was formally adopted used only .ixx and import std.core;. Nice to see MS realized the rest of the world chose a different way to do things.

Importing std.core;, and using .ixx as well, was a huge speed bump/road block for me when first trying to learn C++ modules. The documentation about modules online from sources other than MS used different imports and file extensions. Go figure. *shrug*

One thing about std.core, using it causes VS to produce some really lame warnings about differing compiler switches that are downright annoyingly unnecessary. Use the regular C++ library modules and no warnings.

Yes, the first compilation after importing them causes the library modules to be scanned for module dependencies and compiled, they also get scanned and compiled when doing a full rebuild. If doing a subsequent partial build, and no building or scanning of module dependencies happens.
@George -
The C++20 books I am learning from


Which ones?

I have:
C++20 - The Complete Guide by Nicolai M. Josuttis
C++20 - The Details by Rainer Grimm

I'm waiting for Bartek's C++20 In Detail...
Last edited on
I have "The Complete Guide" as an eBook, haven't really done more than briefly glance at it.

I'm currently slogging my way through "Beginning C++20: From Novice to Professional". A bit more advanced than a "just fell off the turnip truck with ZERO experience" C++ beginner's book, but the C++20 sections are good from what I've read so far. I am going back and forth between chapters 1 and 11 at this time.

Grimm's C++20 eBook is listed as just "C++20" on leanpub (https://leanpub.com/c20). It's on my "to buy" wishlist. As a bundle with "Concurrency with Modern C++", and "The C++ Standard Library." (https://leanpub.com/b/modernccollection)

The In Details book is not listed on Amazon nor leanpub, I don't read Bartłomiej Filipek's blog, so didn't know the book is in the planning stages, let alone published.

I like leanpub because I can purchase a book before it is finished, at a cheaper price than a completed printed book or eBook would be. The eBooks are available in several digital formats.
I don't read Bartłomiej Filipek's blog, so didn't know the book is in the planning stages, let alone published.


As far as I know it's in the planning stage. That's why I'm still waiting for it..

Horton's Beginning c++20 book is my recommendation for a c++ starter book.

Then there's Professional C++ 5th Edition (covers some of c++20 including modules - don't get an earlier edition) by Marc Gregoire. It's more about using C++ than teaching it as it assumes you have some c++ knowledge - although it starts with a crash course.
Last edited on
Now that I know the book is planned I will be more alert to if/when it shows up on leanpub (I hope).

Regarding my original query, in new C++20 code do you primarily use import for the C++ standard library headers, or still use #include?

The C++ library headers make importing vs. including more of a style issue, as I see it.

New modular custom written code is imported, like a fine French wine or cheese.
Planned - but I'm not sure it's yet been started...

For completely new C++ code projects we now use import/export. At the moment for existing projects we've sticking with the #includes that are already there (in this case if it ain't broke don't fix it). Although we are transitioning some of the existing code to C++20 - eg std::format etc.

[PS See my extra edit on my above post after your reply.]

That Pro C++ book does look intriguing, added to my Amazon wishlist.

Heh, I do understand about not willy-nilly changing existing code just because some new feature was added to C++, especially in a potentially HUUUUUUGE code base.

Being self-taught does make it easier to slap together some new feature change/upgrade, most of the code I've written and retained is not that huge, and changes would help to squish the new C++ features further into my cranium. I'm still learning what C++17 added/changed vs. C++11/14. C++20 is for me as radical a change as C++11 was.

For that matter even some C++11 changes are still relatively new to me, such as lambdas.

I may use lambdas, mostly because I copy'n'paste code I've found on the interwebs. Writing one from scratch is intimidating.

I have a handful of header-only files I use routinely, one of which I shamelessly adapted from an old C++ working paper, a simple toolkit to use <random> instead of the C library functions.

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3551.pdf

With a little time and effort I modularized most of my header-only files, though I probably didn't do it as neatly and cleanly as I could and should have done. With minimal testing the interface modules still work as I expect. Later I will examine what can be done to improve what I've already done.

Modularizing the random toolkit was a lot simpler than I thought it would be. Changing inline to export, while substituting module framework for header guards was about all I needed to do.

The MS documentation on modules I read before getting that C++20 book was, to put it politely, confusing to the max.
Last edited on
I must modify somewhat my earlier expressed opinion about the "Beginning C++20" book.

The book jumps straight into showing the C++20 ways of doing things, using std::format to produce formatted output for instance. In other topics the authors rely on using the newest C++ library features before showing pre-C++20 features.

The way C++ should be taught.

I rate this book as probably THE essential beginner's C++ book, as you do, for that reason. And others.

With the caveat ideally someone should learn C++ from multiple sources. Especially if they are self-teaching it. As I am.
Topic archived. No new replies allowed.