0

I'd like to run following code:

#include <iostream>
#include <type_traits>

template<class ... T, class T1, bool B = std::is_integral<T1>::value>
void printIntegrals(T1 thing, T ... stuff) {

    if(B)
        std::cout<<"is integral!"<<std::endl;
    else
        std::cout<<"is not integral!"<<std::endl;

    printIntegrals(stuff ...);
}

template<class T1>
void printIntegrals<{},float>(T1 thing, T ... stuff) {

    std::cout<<"is not integral!"<<std::endl;
}

int main() {

    bool b;
    int i;
    double d;
    char c;
    float f;

    printIntegrals(b, i, d, c, f);
}

However, the specialized template doesn't get initialized. In the compiler error, it is written:

main.cpp:16:6: error: template-id 'printIntegrals<<expression error> >' used as a declarator

which means I'm having a syntactic problem. Is this because the empty initializer list isn't a correct special value for the parameter pack? The idea to create the specialization in this way seems to be correct as the compiler cannot instantiate the following function:

main.cpp: In instantiation of 'void printIntegrals(T1, T ...) [with T = {}; T1 = float; bool B = false]' ...

Update:

The error stem from my confusion with respect to template class specialization and function overloading. Thanks to the comments, I could create this running example:

#include <iostream>
#include <type_traits>

template<class T1, bool B = std::is_integral<T1>::value> void printIntegrals(T1 thing) {

    if(B)
        std::cout<<"is integral!"<<std::endl;
    else
        std::cout<<"is not integral!"<<std::endl;
} 

template<class ... T, class T1, bool B = std::is_integral<T1>::value>
void printIntegrals(T1 thing, T ... stuff) {

    if(B)
        std::cout<<"is integral!"<<std::endl;
    else
        std::cout<<"is not integral!"<<std::endl;

    printIntegrals(stuff ...);
}

int main() {

    bool b{true};
    int i{0};
    double d{.1};
    char c{'a'};
    float f{.1};

    printIntegrals(b, i, d, c, f);
}
FloriHe
  • 73
  • 7
  • Fumction templates cannot be partially specialised. You may want to try overloading instead. – n. m. could be an AI Nov 08 '17 at 13:19
  • Specialization would be `template<> void printIntegrals(float thing)`. but not sure it is what you need. – Jarod42 Nov 08 '17 at 13:20
  • What is `printIntegrals<{},float>`? It looks like you are trying to partially specialize a function template, but that is [not supported](https://stackoverflow.com/q/35000916/3484570). – nwp Nov 08 '17 at 13:20
  • If your goal is to simply check each parameter, and not to bail out of recursion early, for a `float` parameter, then simply get rid of the specialization, and define `void printIntegrals() {}` before the template. Works for me. P.S. Learn about `std::forward` and forwarding references. – Sam Varshavchik Nov 08 '17 at 13:23
  • Correct, I got confused by the "similarity" of template class-specialization and function overloading – FloriHe Nov 08 '17 at 13:31
  • [Possible C++17 implementation](http://coliru.stacked-crooked.com/a/94d25cae10c73266) – Jarod42 Nov 08 '17 at 13:31
  • @n.m.: In the standard, there is an example, where a template function gets explicitly specialized (ch. 14.7.3): `template void sort(Array& v) { /∗ ... ∗/ } template<> void sort(Array&) ; ` So, such a kind of specialization, which I tried to implement in the first place, is possible for functions. – FloriHe Nov 08 '17 at 16:04
  • This is a complete specialisation, not partial. A complete specialisation doesn't have template parameters of its own. Note `template<>` <-- nothing inside angle brackets. – n. m. could be an AI Nov 08 '17 at 16:08
  • Ok, that would have been an alternative way to explain, what a partial specialization is, in the standard :) – FloriHe Nov 08 '17 at 16:19

0 Answers0