Danra
Danra

Reputation: 9916

Way to call a static method of a class template without specifying an instantiation?

Is there any way to define a static method in a class template which can be then be called without specifying the instantiation?

I think this could be useful in cases where you have some auxiliary static function, which logically belongs in a class (which happens to be a template one), but doesn't depend on the template parameter.

I don't mind either:

  1. Having the same static method (including address and all) for all instantiations, or
  2. Having a separate static method for each instantiation, but be able to call the static method without specifying an instantiation where I call the method (some default would be called).

e.g.

template<typename T> class C {
public:
    static int func() { return 0; }
};

int main()
{
    // This works.
    return C<int>::func();   

    // These don't work.
    // return C<>::func();   
    // return C::func();   
}

Upvotes: 4

Views: 2337

Answers (4)

skypjack
skypjack

Reputation: 50550

If you want to get C or C<> to work you can either rely on a base non-template class that contains the given function or use template specializations as it follows:

template<typename...>
struct C;

template<>
struct C<> {
    static int func() { return 0; }
};

template<typename T>
struct C<T>: C<> {
    // all the other things around...
};

int main() {
    C<int>::func();   
    C<>::func();   
}

For you don't provide a definition for the primary template, accepted specializations are:

  • C<> that contains only the given function
  • C<T> that accepts only a parameter as it was in the original example

See it on wandbox.


If you can't use variadic templates, you can still do something similar with a custom type.
As an example:

struct func_only {};

template<typename T = func_only>
struct C;

template<>
struct C<func_only> {
    static int func() { return 0; }
};

template<typename T>
struct C: C<func_only> {
    // all the other things around...
};

int main() {
    C<int>::func();   
    C<>::func();   
}

That being said, make it a free function looks to me as the best solution anyway.

Upvotes: 3

Pascal pizza
Pascal pizza

Reputation: 63

You can use inheritance which will also remove the duplication of any non static functions ( that also don't care about the template type ) in your binary, i.e:

class A {
public:
    static int func() { return 0; }
};

template<typename T> 
class B : A {

};

Upvotes: 3

dascandy
dascandy

Reputation: 7302

How would that work? You typically depend on the type in your static functions too.

template<typename T> class C {
public:
    static int func() { return sizeof(T); }
};

If they do not depend on it, you should probably make them free functions, or static members of a base class of this class.

Upvotes: -1

The simplest solution is probably to have the static function belong in a base class, and then the template derives from the base:

struct CBase {
    static int func() { return 0; }
};

template<typename T> class C : public CBase {
public:
};

int main()
{
    // This works.
    return C<int>::func();

    // This will work too:
    return CBase::func();
}

Upvotes: 4

Related Questions