CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8

Thread: Token pasting

  1. #1
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Token pasting

    Suppose I want to call a function based on the value of some variable - e.g.

    Code:
    if (some_var == 1) {
          helper1_func ();
    } else if (some_var == 2) {
          helper2_func ();
    }
    Obviously that's quite simple but if some_var can have 20 different values it'd soon start to get pretty convoluted. Is there a cleverer way to do this (e.g. with token pasting or something like that?)
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Token pasting

    Can you use switch statement?
    Victor Nijegorodov

  3. #3
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Token pasting

    Yeah, I could use switch or even an array of function pointers but I'm just wondering if there's some cleverer way

    I've a vague feeling I once saw something like this done with token pasting but I could easily be wrong about that...
    Last edited by John E; May 29th, 2018 at 03:31 AM.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

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

    Re: Token pasting

    I would think that using the preprocessor for this is a hack compared to just using an array of function pointers.
    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

  5. #5
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Token pasting

    Oops, good point.! The value of some_var won't even be known until run time so I must be getting mixed up with something else...
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  6. #6
    Join Date
    Feb 2017
    Posts
    677

    Re: Token pasting

    Quote Originally Posted by John E View Post
    if there's some cleverer way
    If you need a mapping then a clever way is to use an std::unordered_set/map. It's fast (O(1)) and flexible (selections can be added/removed also at runtime).

    Another clever way is to use Object Oriented programming (OO). OO uses so called dynamic polymorphism to avoid the kind of selections you describe in your original post. In principle "arrays of function pointers" are used and in languages with OO support they're part of the language. In C++ they're known as virtual function tables (vtables) and a function call that's directed via a vtable is called a dynamic dispatch.

    There are perfectly legitimate reasons to use explicit mappings in OO of course but generally you avoid them by OO design (and all polymorphic mappings involved will take place automagically behind the curtain). So if you tend to have lots of if-else chains, switches and jump tables in your code to express logical flow, consider an OO design.
    Last edited by wolle; June 3rd, 2018 at 10:51 AM.

  7. #7
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: Token pasting

    Using macros works. Usually macros are frowned upon, but in certain cases they can be useful.
    Another option, maybe you can use the command pattern.
    See also: https://stackoverflow.com/questions/...ode-dispatcher
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  8. #8
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Token pasting

    You can also use a lambda rather than a function - so can capture variables by ref if needed. Consider the code below (which is some test code for something slightly different but the general point is still there)

    Code:
    #include <iostream>
    #include <utility>
    #include <map>
    #include <functional>
    using namespace std;
    
    enum class Color {Red, Blue};
    enum class Size {Small, Medium, Large};
    
    void process(Color c, Size s)
    {
    	using cskey = pair<Color, Size>;
    	using csfunc = function<void()>;
    	using csmap = map<cskey, csfunc>;
    
    	static const csfunc rs = []() {cout << "rs\n"; };
    	static const csfunc rm = []() {cout << "rm\n"; };
    	static const csfunc rl = []() {cout << "rl\n"; };
    	static const csfunc bs = []() {cout << "bs\n"; };
    	static const csfunc bm = []() {cout << "bm\n"; };
    	static const csfunc bl = []() {cout << "bl\n"; };
    
    	static const csmap mapping {{{Color::Red, Size::Small}, rs}, {{Color::Red, Size::Medium}, rm}, {{Color::Red, Size::Large}, rl},
    							{{Color::Blue, Size::Small}, bs}, {{Color::Blue, Size::Medium}, bm}, {{Color::Blue, Size::Large}, bl}};
    
    	if (auto mit = mapping.find({c, s}); mit != mapping.end())
    		mit->second();
    	else
    		throw (runtime_error("Bad key"));
    }
    
    int main()
    {
    	try {
    		process(Color::Blue, Size::Small);
    	}
    	catch (const runtime_error& re) {
    		cout << re.what() << endl;
    	}
    }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

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