Toni Makkonen
Toni Makkonen

Reputation: 141

Overloading C++ functions without passing parameters

Is it possible in C++ to use some sort of identifiers akin to function arguments to overload functions? This would allow easier use with templates. It would also make the code look nicer for my particular case, which I'm not explaining in detail.

In case that didn't make much sense, and I honestly don't even know the right keywords for this (please let me know), here's a toy example:

I want writing something like this

function(i);
function(special_action);
function(special_action_2);

being understood like this

function(i);
function_special_action();
function_special_action_2();

What is the best way of achieving this? So far, I have tried doing dummy enums like this:

// normal action
void function(int i) { ... }

// special actions
enum dummy_enum_for_special_action { special_action };
void function(const dummy_enum_for_special_action & dummy) { ... }

I'm guessing the parameter passing will be optimized away by the compiler. Is there, however, a better way of doing this?

Upvotes: 3

Views: 204

Answers (2)

Stefano Falasca
Stefano Falasca

Reputation: 9097

you can use a series of dummy types for "tagging" the different functions. Here's an example

#include <iostream>

using namespace std;

template <typename tag>
void func(const tag&);

struct First{};
First first;

template <>
void func(const First&){
    cout << "funcFirst" << endl;
}

struct Second{};
Second second;

template <>
void func(const Second&){
    cout << "funcSecond" << endl;
}

struct Third{};
Third third;

void func(const Third&){
    cout << "funcThird" << endl;
}

int main()
{
    func(first);
    func(second);
    func(third);
}

which you can try here.

Of course, I suggest you to use proper namespaces, as to avoid problems with such global definitions, i particular for what concerns "first" and "second" (in my example).

Notice that you don't even need to make the function a template, this is just one possibility. You can rely on simple overloading, as in func(const Third&).

Upvotes: 2

Konrad Rudolph
Konrad Rudolph

Reputation: 545953

This is know as “tag dispatch” and it’s a pretty common technique with libraries that offer generic functions (such as the standard <algorithms> library).

Just use separate tag types for the parameters:

struct i { }; // bad name.
struct special_action { };
struct special_action_2 { };

Function declarations:

void function(i) { … }
void function(special_action) { … }
void function(special_action_2) { … }

And call like this:

function(i());
function(special_action());
function(special_action_2());

Alternatively, if you want to get rid of the parentheses, use global instances (but I’m not sure that’s a good idea);

namespace { // See comment below
    struct i_t { } i;
    // etc …
}

void function(i_t) { … }
// etc …

The unnamed namespace is necessary to avoid violating the one definition rule for the variable names declared at global scope.

Upvotes: 3

Related Questions