C++构造函数的模板特化

发布于 2024-08-14 22:43:15 字数 568 浏览 5 评论 0原文

我有一个模板类 A和两个 typedef A和A<弦,30>。 如何重写 A的构造函数?以下不起作用:

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 {
public:
  A(int m) {test= (m>M);}

  bool test;

};


template<>
one_type::one_type() { cerr << "One type" << endl;}

我想要 A 类做其他班级没有做的事情。如何在不更改构造函数 A:A(int) 的情况下执行此操作?

I have a templated class A<T, int> and two typedefs A<string, 20> and A<string, 30>.
How do I override the constructor for A<string, 20> ? The following does not work:

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 {
public:
  A(int m) {test= (m>M);}

  bool test;

};


template<>
one_type::one_type() { cerr << "One type" << endl;}

I would like the class A<std::string,20> to do something that the other class doesn't. How can I do this without changing the constructor A:A(int) ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

╰沐子 2024-08-21 22:43:15

迟到但非常优雅的解决方案:
C++ 2020 引入了约束和概念。您现在可以有条件地启用和禁用构造函数和析构函数!

#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;
};

此处运行代码。

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.

温柔嚣张 2024-08-21 22:43:15

您唯一不能做的就是使用 typedef 来定义构造函数。除此之外,您应该像这样专门化 A 构造函数:

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

如果您希望 A 有一个不同的< /em> 构造函数而不是通用的 A,您需要专门化整个 A 类:

template<> class A<string,20> {
public:
   A(const string& takethistwentytimes) { cerr << "One Type" << std::endl; }
};

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; }
};
烦人精 2024-08-21 22:43:15

假设您的确实意味着A::test可以公开访问,您可以这样做:

#include <iostream>


template <int M>
struct ABase
{
  ABase(int n) : test_( n > M )
  {}

  bool const test_;
};


template <typename T, int M>
struct A : ABase<M>
{
  A(int n) : ABase<M>(n)
  {}
};


template <typename T>
A<T, 20>::A(int n)
  : ABase<20>(n)
  { std::cerr << "One type" << std::endl; }

踢一下轮胎:

int main(int argc, char* argv[])
{
  A<int, 20> a(19);
  std::cout << "a:" << a.test_ << std::endl;
  A<int, 30> b(31);
  std::cout << "b:" << b.test_ << std::endl;
  return 0;
}

Assuming your really meant for A::test to be publicly accessible, you could do something like this:

#include <iostream>


template <int M>
struct ABase
{
  ABase(int n) : test_( n > M )
  {}

  bool const test_;
};


template <typename T, int M>
struct A : ABase<M>
{
  A(int n) : ABase<M>(n)
  {}
};


template <typename T>
A<T, 20>::A(int n)
  : ABase<20>(n)
  { std::cerr << "One type" << std::endl; }

Kick the tires:

int main(int argc, char* argv[])
{
  A<int, 20> a(19);
  std::cout << "a:" << a.test_ << std::endl;
  A<int, 30> b(31);
  std::cout << "b:" << b.test_ << std::endl;
  return 0;
}
单身狗的梦 2024-08-21 22:43:15

这可能有点晚了,但是如果您可以访问 c++11,您可以使用 SFINAE 来完成你想要的:

  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
  }

工作示例

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

葬シ愛 2024-08-21 22:43:15

怎么样:

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
    }
};

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
    }
};
污味仙女 2024-08-21 22:43:15

您目前的方法无法做到这一点。 one_type 是特定模板专业化的别名,因此它获取模板具有的任何代码。

如果要添加特定于 one_type 的代码,则必须将其声明为 A 专业化的子类,如下所示:

  class one_type:
    public A<std::string, 20>
  {
    one_type(int m)
      : A<str::string, 20>(m)
    {
      cerr << "One type" << endl;
    }
  };

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;
    }
  };
把人绕傻吧 2024-08-21 22:43:15

对于这种情况,我能想到的最佳解决方案是使用“构造函数辅助函数”:

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;}

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;}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文