Home > Enterprise >  Can I make a function that returns a different type depending on a template argument, without using
Can I make a function that returns a different type depending on a template argument, without using

Time:12-11

This is almost what I want and it works:

int abc(int) {
    return 5;
}

float abc(float) {
    return 8.0;
}


int main() {
    std::cout << abc(1) << "\n";
    std::cout << abc(1.0f) << "\n";
}

But I don't want to pass dummy parameters into the function. I want to have some sort of function and then use it like this:

int main() {
    std::cout << abc<int>() << "\n";
    std::cout << abc<float>() << "\n";
}

Is that possible?

CodePudding user response:

No need to define functors as in Mayolo's answer. You can simply specialize a function template:

#include<iostream>

template<typename T>
T foo();

template<>
int foo() {
    return 5;
}

template<>
double foo() {
    return 8.0;
}

int main() {
    std::cout << foo<int>() << "\n";
    std::cout << foo<double>() << "\n";
}

Try it yourself!

CodePudding user response:

In your case a template variable might make more sense:

template <class T> constexpr T abc;

template <>
constexpr inline int abc<int> = 5;

template <>
constexpr inline float abc<float> = 8.5f;

int main()
{
    int i = abc<int>;
    float f = abc<float>;

    long x = abc<long>; // error
}

CodePudding user response:

You may do with help of if-constexpr (or runtime if in such a simple case) the exact syntax you want

#include <iostream>
#include <type_traits>

template <typename T>
T abc() {
    if constexpr (std::is_integral_v<T>)
        return 5;
    else if constexpr (std::is_floating_point_v<T>)
        return 8.0;
    else
        return {};
}
template <typename T>
T abc() {
    if (std::is_integral_v<T>)
        return 5;
    else if (std::is_floating_point_v<T>)
        return 8.0;
    else
        return {};
}
int main() {
    std::cout << abc<int>() << "\n";
    std::cout << abc<float>() << "\n";
}

CodePudding user response:

Yes, but not with that exact syntax. Functions can't have template specializations (only overloads), but structs can. Consider

template <typename T>
struct abc;

template <>
struct abc<int> {
  int operator()() {
    return 5;
  }
}

template <>
struct abc<float> {
  float operator()() {
    return 8.0;
  }
}

Then call as

std::cout << abc<int>()() << "\n";
std::cout << abc<float>()() << "\n";
  •  Tags:  
  • c
  • Related