4

I'm trying to do something like:

#pragma once
#include <memory>
#include <type_traits>
#include <vector>

class B{}

template <class T>
class A
{
    private:
        std::vector<std::shared_ptr<T>> ptrVector;
    public:
        A<T>();
        void pushBack(std::shared_ptr<T> t);
        if(std::is_same<T, B>::value)
        {
            void doSth();
        }
        ~A<T>(){};
};

is it even possible to do a condition like this, somehow? No, I can't inherit from this class, and need doSth() ONLY if A<B>, the doSth() should not exist if A<C>.

Farkor123
  • 39
  • 4

2 Answers2

5

You can use std::enable_if to conditionally make doSth available without having to specialize the entire class:

template <class T>
class A
{
    private:
        std::vector<std::shared_ptr<T>> ptrVector;
    public:
        A<T>();
        void pushBack(std::shared_ptr<T> t);    

        template <typename U = T>
        auto doSth() -> std::enable_if_t<std::is_same<U, B>::value>;     

        ~A<T>(){};
};

You need template <typename U = T> because std::enable_if_t relies on SFINAE. See std::enable_if to conditionally compile a member function for more information.

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • 1
    Thats EXACTLY what i was looking for, thanks a lot <3 – Farkor123 Nov 22 '17 at 10:58
  • Interesting construction. Can you 1) explain the `->` construction a bit more, and 2) explain what `auto` does in this context? – Chiel Nov 22 '17 at 11:10
  • 1
    @Chiel: `auto foo(...) -> R` is a *trailing return type*, introduced in C++11. https://www.ibm.com/developerworks/community/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/introduction_to_the_c_11_feature_trailing_return_types?lang=en – Vittorio Romeo Nov 22 '17 at 11:16
  • [hpp](https://hastebin.com/xijiqocupe.hpp) , [cpp](https://hastebin.com/uzokulepoz.cpp) , these are the files i wrote, but i keep getting error: prototype in .cpp doesn't match any in .h. How should it look? – Farkor123 Nov 22 '17 at 11:51
2

You can do it with a full specialization. e.g.

class B {};

template <class T>
class A
{
    private:
        std::vector<std::shared_ptr<T>> ptrVector;
    public:
        A();
        void pushBack(std::shared_ptr<T> t);
        ~A(){};
};

template <>
class A<B>
{
    private:
        std::vector<std::shared_ptr<B>> ptrVector;
    public:
        A();
        void pushBack(std::shared_ptr<B> t);
        void doSth();
        ~A(){};
};

You can also consider about making a common base class to avoid code duplication.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405