LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   C++ template function default type and value? (https://www.linuxquestions.org/questions/programming-9/c-template-function-default-type-and-value-938658/)

johnsfine 04-07-2012 02:37 PM

C++ template function default type and value?
 
I want to define a function in which the type of one of the inputs is a template parameter (inferred if the input is given) but that input is also optional with a default value.

Is there any correct syntax for that in C++?

Incorrect syntax demonstrating what I want to do is:
Code:

struct nothing {};

template< class T >
int test_template(int x, T const& y = nothing()) {
    return x;
}

int test() {
    int i = test_template(1);
    int j = test_template(2,3);
    int k = test_template<nothing>(4);
    return i+j;
}

g++ complains about test_template(1) because it can't infer the type T. Other compilers are OK with that line but complain about test_template(2,3), which g++ likes but the other compilers complain the default value is incompatible with the inferred type, which is true but a really annoying check since the default value isn't used in the case where it isn't compatible. All the compiler are OK with test_template<nothing>(4) but that is only there for illustration. It isn't actually helpful.

Logically the code might be this instead, but no compiler likes this either:
Code:

struct nothing {};

template< class T = nothing >
int test_template(int x, T const& y = T()) {
    return x;
}

int test() {
    int i = test_template(1);
    int j = test_template(2,3);
    int k = test_template<nothing>(4);
    return i+j;
}

In the real use, the function replacing test has a lot of templated parameters before the one I want to default and does a lot of complicated operations on them and needs a compile time check (which I know how to code) on whether the defaulted parameter has type nothing to remove code that should only be present if that parameter was provided.

The best, but ugly, solution I can find is equivalent to:
Code:

struct nothing {};

template< class T>
int test_template(int x, T const& y) {
    return x;
}

int test_template(int x) {
    return test_template(x, nothing());
}

int test() {
    int i = test_template(1);
    int j = test_template(2,3);
    return i+j;
}

Anyone have any better ideas?

dwhitney67 04-07-2012 03:22 PM

Quote:

Originally Posted by johnsfine (Post 4647299)
Logically the code might be this instead, but no compiler likes this either:
Code:

struct nothing {};

template< class T = nothing >
int test_template(int x, T const& y = T()) {
    return x;
}

int test() {
    int i = test_template(1);
    int j = test_template(2,3);
    int k = test_template<nothing>(4);
    return i+j;
}


Actually, if you compile the code above with g++, providing the -std=c++0x compiler option, then it does compile successfully.

ta0kira 04-07-2012 04:19 PM

Quote:

Originally Posted by johnsfine (Post 4647299)
The best, but ugly, solution I can find is equivalent to:
Code:

struct nothing {};

template< class T>
int test_template(int x, T const& y) {
    return x;
}

int test_template(int x) {
    return test_template(x, nothing());
}

int test() {
    int i = test_template(1);
    int j = test_template(2,3);
    return i+j;
}


This seems like the most logical solution, unless you want to count on having C++0x support (as in dwhitney67's suggestion.) If you're using templates as a preprocessor to control the code in the function, I'm sure you have other template code that's substantially uglier than a wrapper function.
Kevin Barry

tuxdev 04-09-2012 01:34 PM

Quote:


Logically the code might be this instead, but no compiler likes this either:
Code:

struct nothing {};

template< class T = nothing >
int test_template(int x, T const& y = T()) {
    return x;
}

int test() {
    int i = test_template(1);
    int j = test_template(2,3);
    int k = test_template<nothing>(4);
    return i+j;
}


In non-0x C++ you still need <> on the calls to test_template<>() even if the actual types are inferred/defaulted.


All times are GMT -5. The time now is 01:47 AM.