10

Is there a way to alias a static member function in C++? I would like to be able to pull it into scope so that I do not need to fully qualify the name.

Essentially something like:

struct Foo {
  static void bar() {}
};

using baz = Foo::bar; //Does not compile

void test() { baz(); } //Goal is that this should compile

My first thought was to use std::bind (as in auto baz = std::bind(Foo::bar);) or function pointers (as in auto baz = Foo::bar;), but that is unsatisfactory because for each function I want to be able to use the alias in, I need to make a separate variable just for that function, or instead make the alias variable available at global/static scope.

Mark
  • 3,806
  • 3
  • 21
  • 32
  • 1
    can you make `Foo` a namespace? – Bryan Chen Feb 18 '15 at 04:11
  • 1
    What's wrong with an alias variable in global scope? However, you should use `constexpr`: `constexpr auto baz = &Foo:bar;` Your goal is to introduce the name in that scope, and `constexpr` does exactly that. – Ben Voigt Feb 18 '15 at 04:11
  • +1 for suggestion to use constexpr. I mostly didn't want to have to worry about initialization of globals. Global initialization is tricky business. Was hoping there'd be a mechanic in the language that simply deals with scoping. – Mark Feb 18 '15 at 04:14
  • 1
    It's still a "global" even if it has `constexpr` – M.M Feb 18 '15 at 04:15
  • Yes, but it's better with than without. Would also want to add `const` (since that's no longer included as part of `constexpr` in C++14 as I recall it. – Mark Feb 18 '15 at 04:18
  • 1
    @Mark `constexpr`-no-longer-`const` is for member functions. – T.C. Feb 18 '15 at 06:35

2 Answers2

12

using is not the correct tool here. Simply declare your alias (as global if you need to) with auto baz = &Foo::bar.

As suggested in the comments, you can also make it constexpr to have it available, when possible, at compile-time in constant expressions.

struct Foo {
  static void bar() { std::cout << "bar\n"; }
};

constexpr auto baz = &Foo::bar; 

void test() { baz(); }

int main() 
{
    test();
}

Demo

quantdev
  • 23,517
  • 5
  • 55
  • 88
  • Apologies for not being clearer. I do not want the type. I want to have the function in scope without having to fully qualify it. Will edit the question. – Mark Feb 18 '15 at 04:05
  • 2
    @Mark is [this](http://coliru.stacked-crooked.com/a/a973d9d8a871acf7) what you are looking for ? – quantdev Feb 18 '15 at 04:11
  • yes, that is the effect I'm looking for, I just didn't want to depend on initialization of globals. – Mark Feb 18 '15 at 04:12
  • 2
    @Mark you can rely on globals whose usage is in the same .cpp file as their definition – M.M Feb 18 '15 at 04:14
  • @MattMcNabb - True, but that means I've changed the duplication problem from once per function to once per cpp file. Better, but still not great, and a non-solution if I need templates. – Mark Feb 18 '15 at 04:15
  • @MattMcNabb - On second thought, that's essentially the same I'd expect from a using statement to pull things into scope, since you're not supposed to use those in header files anyway (except inside function scopes). +1. Just need to make the variables `static const constexpr`, which is a mouthful. – Mark Feb 18 '15 at 04:31
  • What if Foo::bar is overloaded?. I'm getting `has incompatible initializer of type ''` – benathon Mar 31 '20 at 00:01
  • The `alias` function pointer looses default arguments, if there are any. – dyoll Nov 04 '21 at 12:31
0

Not a very direct way, but can use function pointer.

void (*baz)()  = Foo::bar; //Does not compile

Now you can simply call baz(); for Foo::bar;

Pranit Kothari
  • 9,721
  • 10
  • 61
  • 137
  • This is an uglier form of one of the unsatisfactory solutions I listed in the OP. – Mark Feb 18 '15 at 04:08
  • @Mark: It's better, because no useless use of `std::bind`. Of course, also using `auto` would be even better. – Ben Voigt Feb 18 '15 at 04:10
  • @BenVoigt - bind was one of two solutions I listed in the OP. The second one used auto. I refer to the one using auto. – Mark Feb 18 '15 at 04:11
  • @Mark I was not able to mentally deduce `auto`. Secondly I don't think it's ugly way. I already mentioned it is not very standard solution. Why you think it's bad? – Pranit Kothari Feb 18 '15 at 04:17
  • @PranitKothari - I'll remove the -1, but I don't think this is a good answer. It is a restatement of a solution I gave in the original question with a less satisfactory syntax. See other comments on other parts of this thread for why I don't find this general solution satisfactory. – Mark Feb 18 '15 at 04:21
  • Apparently I can't take it back at this point actually (time limit)... just as well. – Mark Feb 18 '15 at 04:22
  • @Mark It's not only for -1, I just wanted to know ugly part.. because I have been using function pointer from long time.. – Pranit Kothari Feb 18 '15 at 04:22
  • @PranitKothari - I suppose I just quite dislike function pointer syntax. Nothing about it seems clean. It's kinda like how we deprecated typedef in favour of using aliases because they're more uniform. FP syntax is a sore thumb in the language. In this particular case, it was made worse in that it obfuscates the purpose of the line. It's not clear that that line is creating an alias. `auto` is cleaner. I suppose because that is a matter of personal opinion, if you edit your answer, I think it will let me take back that -1. – Mark Feb 18 '15 at 04:27