C++ single template specialisation with multiple template parameters

Viewed 22061

Hallo!

I would like to specialise only one of two template types. E.g. template <typename A, typename B> class X should have a special implementation for a single function X<float, sometype>::someFunc().

Sample code:

main.h:

#include <iostream>

template <typename F, typename I>
class B
{
public:
    void someFunc()
    {
        std::cout << "normal" << std::endl;
    };

    void someFuncNotSpecial()
    {
        std::cout << "normal" << std::endl;
    };
};

template <typename I>
void B<float, I>::someFunc();

main.cpp:

#include <iostream>
#include "main.h"

using namespace std;

template <typename I>
void B<float, I>::someFunc()
{
    cout << "special" << endl;
}

int main(int argc, char *argv[])
{
    B<int, int> b1;
    b1.someFunc();
    b1.someFuncNotSpecial();

    B<float, int> b2;
    b2.someFunc();
    b2.someFuncNotSpecial();
}

Compilation fails for class B. Is it true, that this is not possible in C++ in this way? What would be the best workaround?

[edit]

template <float, typename I> void B<float, I>::someFunc(); leads to main.h:26: error: ‘float’ is not a valid type for a template constant parameter

template <typename I> void B<float, I>::someFunc(); leads to main.h:27: error: invalid use of incomplete type ‘class B’

And I'm using gcc.

[edit]

I don't want to specialise the whole class, as there are other functions that don't have a specialisation.

4 Answers

I think C++ expert Mayer provides us an elegant function. Cons is it depends on GCC feature.

#include <map>
#include <iostream>
#include <string>

using namespace std;


template<typename... T>
void TemplatePrint(T... args) {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}


int main()
{
    map<string, int> arr={{"1", 1}, {"2", 2}, {"3", 3}};
    auto itr = arr.find("3");
    TemplatePrint<decltype(itr)>(itr);


    return 0;
}

GCC will print out real decltype of iterator (really real), which is :

void TemplatePrint(T ...) [with T = {std::_Rb_tree_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >}]
Related