C++11 - Compile time Polymorphism solutions

泪湿孤枕 提交于 2019-12-10 17:24:06

问题


Suppose that I'm writing a cross-platform library, I have to organize the code in a way that there is a different behaviour for different platforms and this behaviour ( or definition ) it's choosen at compile time based on the platform where my library it's being compiled.

The "usual" way to do this in C++ is to pollute the code with a lot of #ifdef when writing a method or a class.

The problem with approach is that:

  • the source code looks really ugly
  • if you are supporting 3 platforms, your source code is about 3 times larger than what you really need, meaning that your compiler still needs to parse and analyze all the code to "see" the #ifdef
  • there is no real distinctions between different implementations, it's hard to mantain when the code base is growing, and when you simply have just 3-4 platforms, it grows really fast.

Since there are a lot of new features in C++11 I was wondering if something is changed and if there are new options for this.


回答1:


You should be using your build system to do this. You should provide headers with platform-independent declarations of functions and definitions of classes. Then, depending on the target platform, the build system should compile the appropriate implementations of those functions and classes.

For example, let's consider the creation of windows for displaying graphics or GUI elements. If you're not using a library to do this, you have to write the cross-platform code yourself. First, you should think about exactly what the platform-independent interface should be. Perhaps you have a window class and some helper functions. You could then provide the definition for that class and the declarations of the helper functions in a header file and provide separate implementations for each platform. Then you'll have a set of files like this:

  • window.h
  • window_wayland.cpp
  • window_winapi.cpp
  • window_x11.cpp

Now, all of the files that need to use your class and functions should just #include <window.h>. They all get the same function declarations. However, you specify in the configuration of your build system that window_x11.cpp should be compiled on systems with the X11 windowing system, window_wayland.cpp on systems with Wayland, and window_winapi on Windows. This means that depending on the platform you're building on, you will get an implementation of that header that works on the target platform.

This has a good few advantages:

  1. You've separated build concerns (which platform you're building for) from code concerns.
  2. Each platform-dependent implementation has its own file.
  3. You don't have a file cluttered with preprocessor directives and hard to follow execution paths.

This doesn't mean there's anything wrong with using defines to selectively compile different parts of your code. I prefer to see this only with small amounts of code that has been localized to the platform-dependent parts. Ideally, wrap the platform-dependent code in a function and have the #ifdefs just swap out the implementation.

Exactly how you do this selective building depends on the build system you're using. For the GNU build system, you can achieve conditional compilation with automake. Some examples are given in the documentation. A simple example given is:

bin_PROGRAMS = hello
if LINUX
hello_SOURCES = hello-linux.c hello-common.c
else
hello_SOURCES = hello-generic.c hello-common.c
endif

Running automake with this configuration will generate the appropriate makefile.



来源:https://stackoverflow.com/questions/15849419/c11-compile-time-polymorphism-solutions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!