0

Below is the code

template <class T>
class Demo
{
public:
    T var;
    Demo(T a)
    {
        var = a;
    }
    void PrintDemo()
    {
        cout << "In generic PrintDemo " << var << endl;
        cout << "Var is " << var << endl;
    }
    template<typename int>
    void PrintDemo()
    {
        cout << "In int PrintDemo " << var << endl;
        cout << "Var is " << var << endl;
    }
};

When I compile this code, I get below error:

main.cpp:18:23: error: expected nested-name-specifier before ‘int’
   18 |     template<typename int>

Can some one help me out to understand the error?

This is my requirement. But I am not able to compile it.

kirant
  • 11
  • 2
  • you have a class template so you need to specialize the class – 463035818_is_not_an_ai Dec 06 '22 at 18:27
  • 2
    Can you explain, in your own words, what you expect `template` to do? What is the results of that? And what does specialization have to do with this? – Sam Varshavchik Dec 06 '22 at 18:31
  • See dupe: [Specialize member function of class template using C++20 concepts](https://stackoverflow.com/questions/71025802/specialize-member-function-of-class-template-using-c20-concepts) and [Partial template specialization on class methods using enable_if](https://stackoverflow.com/questions/74323336/partial-template-specialization-on-class-methods-using-enable-if) – Jason Dec 07 '22 at 13:05

3 Answers3

1

void PrintDemo() is not a template, there is nothing to specialize. If you want to call specific function based on class template parameter, you can use concept to achieve it. (with c++20)

template <class T>
class Demo
{
public:
    T var;
    Demo(T a = 0)
    {
        var = a;
    }
    void PrintDemo()
    {
        cout << "In generic PrintDemo " << var << endl;
        cout << "Var is " << var << endl;
    }

    void PrintDemo() requires std::same_as<T,int>
    {
        cout << "In int PrintDemo " << var << endl;
        cout << "Var is " << var << endl;
    }
};

or you can use constexpr if in c++17

apple apple
  • 10,292
  • 2
  • 16
  • 36
1

Besides the examples given, another way is to use std::enable_if<>:

#include <type_traits>
#include <boost/utility.hpp>

template <class T>
class Demo
{
public:
    T var;
    Demo(T a)
    {
        var = a;
    }

    boost::disable_if_t<std::is_same_v<T, int>>
    PrintDemo()
    {
        cout << "In generic PrintDemo " << var << endl;
        cout << "Var is " << var << endl;
    }

    std::enable_if_t<std::is_same_v<T, int>>
    PrintDemo()
    {
        cout << "In int PrintDemo " << var << endl;
        cout << "Var is " << var << endl;
    }
};

In the generic case, when you have a return type, you might specify it as the second type argument of std::enable_if / std::disable_if (e.g. std::enable_if_t<std::is_same_v<T, int>, bool> for a function returning bool value).

If you don't want to include boost for this, you can also define disable_if simply as:

template<bool B, class T = void>
struct disable_if {};
 
template<class T>
struct disable_if<false, T> { typedef T type; };

template<bool B, typename T = void>
using disable_if_t = typename disable_if<B, T>::type;
lorro
  • 10,687
  • 23
  • 36
  • `disable_if` ? Does this exist? Even if yes, this expands to `int void PrintDemo() { ...` – 463035818_is_not_an_ai Dec 06 '22 at 18:55
  • @463035818_is_not_a_number Yep, it's boost, not std, but it exists and expands as expected: OP wanted an int an a non-int version of `PrintDemo()`. – lorro Dec 07 '22 at 12:45
  • ok, but i think you mean `boost::disable_if_t> PrintDemo()` rather than `boost::disable_if_t> void PrintDemo()`. Your non-int overload has return type `void void` ... – 463035818_is_not_an_ai Dec 07 '22 at 12:59
  • 1
    @463035818_is_not_a_number Ah yes, typo, sorry for that. Thanks for spotting, fixed. – lorro Dec 07 '22 at 13:48
  • would be nice to add the includes. Especially with boost i find it extremely hard to browse documentation to find in which header something is declared – 463035818_is_not_an_ai Dec 07 '22 at 13:55
  • 1
    @463035818_is_not_a_number Added, also added a definition for that - in case someone doesn't want to bring boost in as a dependency. – lorro Dec 07 '22 at 14:03
0

You cannot specialise only one function within a class template, as you have to specialise the class template as a whole:

template <>
class Demo<int> {
public:
    int var;
    Demo(int a) {
        var = a;
    }

    void PrintDemo() {
        std::cout << "In generic PrintDemo " << var << std::endl;
        std::cout << "Var is " << var << std::endl;
    }
};

Alternatively you can specialise the function outside of the class declaration:

template<>
void Demo<int>::PrintDemo() {
    std::cout << "In generic PrintDemo " << var << std::endl;
    std::cout << "Var is " << var << std::endl;
}
The Dreams Wind
  • 8,416
  • 2
  • 19
  • 49