C++ template specialization of constructor

后端 未结 7 904
醉话见心
醉话见心 2021-02-05 17:15

I have a templated class A and two typedefs A and A. How do I override the constructor for A ? The following does not wor

相关标签:
7条回答
  • 2021-02-05 17:34

    You can't with your current approach. one_type is an alias to a particular template specialization, so it gets whatever code the template has.

    If you want to add code specific to one_type, you have to declare it as a subclass of A specialization, like this:

      class one_type:
        public A<std::string, 20>
      {
        one_type(int m)
          : A<str::string, 20>(m)
        {
          cerr << "One type" << endl;
        }
      };
    
    0 讨论(0)
  • 2021-02-05 17:39

    This may be a little bit late, but if you have access to c++11 you can use SFINAE to accomplish just what you want:

      template <class = typename std::enable_if< 
        std::is_same<A<T,M>, A<std::string, 20>>::value>::type // Can be called only on A<std::string, 20>
      > 
      A() {
        // Default constructor
      }
    

    Working example

    0 讨论(0)
  • 2021-02-05 17:39

    How about :

    template<typename T, int M, bool dummy = (M > 20) >
    class A {
    public:
      A(int m){
          // this is true
      }
    
    };
    
    template<typename T, int M>
    class A<T,M,false> {
    public:
        A(int m) {
        //something else
        }
    };
    
    0 讨论(0)
  • 2021-02-05 17:41

    Late but a very elegant solution: C++ 2020 introduced Constraints and Concepts. You can now conditionally enable and disable constructors and destructors!

    #include <iostream>
    #include <type_traits>
    
    template<class T>
    struct constructor_specialized
    {
        constructor_specialized() requires(std::is_same_v<T, int>)
        {
            std::cout << "Specialized Constructor\n";
        };
    
        constructor_specialized()
        {
            std::cout << "Generic Constructor\n";
        };
    };
    
    int main()
    {
        constructor_specialized<int> int_constructor;
        constructor_specialized<float> float_constructor;
    };
    

    Run the code here.

    0 讨论(0)
  • 2021-02-05 17:46

    The only thing you cannot do is use the typedef to define the constructor. Other than that, you ought to specialize the A<string,20> constructor like this:

    template<> A<string,20>::A(int){}
    

    If you want A<string,20> to have a different constructor than the generic A, you need to specialize the whole A<string,20> class:

    template<> class A<string,20> {
    public:
       A(const string& takethistwentytimes) { cerr << "One Type" << std::endl; }
    };
    
    0 讨论(0)
  • 2021-02-05 17:50

    The best solution I've been able to come up with for this situation is to use a "constructor helper function":

    template <typename T, int M> class A;
    typedef  A<std::string, 20> one_type;
    typedef  A<std::string, 30> second_type;
    
    template <typename T, int M>
    class A {
    private:
      void cons_helper(int m) {test= (m>M);}
    public:
      A(int m) { cons_helper(m); }
    
      bool test;
    };
    
    template <>
    void one_type::cons_helper(int) { cerr << "One type" << endl;}
    
    0 讨论(0)
提交回复
热议问题