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.

3

3 Answers 3

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

Sign up to request clarification or add additional context in comments.

Comments

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;

6 Comments

disable_if ? Does this exist? Even if yes, this expands to int void PrintDemo() { ...
@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().
ok, but i think you mean boost::disable_if_t<std::is_same_v<T, int>> PrintDemo() rather than boost::disable_if_t<std::is_same_v<T, int>> void PrintDemo(). Your non-int overload has return type void void ...
@463035818_is_not_a_number Ah yes, typo, sorry for that. Thanks for spotting, fixed.
@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.
|
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;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.