构造函数模板

Constructor Template

本文关键字:函数模板      更新时间:2023-10-16

我有一个有几个构造函数的类。根据通过argv传递给main()的参数,我想在不同的构造函数之间切换。下面的简化示例在"obj"更改为class的情况下工作得很好,我使用例如obj1->int和obj2->double。但是我需要做些什么来让下面的代码使用enum运行呢?

#include<iostream>
using namespace std;
enum obj{obj1,obj2};
template <obj T>
class A
{
public:
  A(T);
private:
  T t_;
};
template<obj T>
A<T>::A(T )
{}
template<>
A<obj1>::A(obj1 t):t_(t) {cout<<"case 1"<< endl;}
template<>
A<obj2>::A(obj2 t):t_(t) {cout<<"case 2"<< endl;}
int main()
{
    obj test=obj1;
    A<obj> a(test);
    return 1;
}

谢谢你的帮助!

编辑:很明显,关于类型/值的代码是错误的,但是哪种机制可以类似于这样的构造函数切换?

您必须专门化类型,而不是值。如果在编译时知道这个值,可以使用boost::mpl::int_来实现。如果您不这样做(就像您的情况一样),您将不得不使用普通的旧if

我认为你打算这样做:

#include<iostream>
enum obj{obj1,obj2};
template<obj>
class A
{
public:
    A();
private:
    obj t_;
};
template<obj x>
A<x>::A() : t_(x){}
template<>
A<obj1>::A() : t_(obj1){ std::cout << "obj1n"; }
template<>
A<obj2>::A() : t_(obj2){ std::cout << "obj1n"; }
int main()
{
    const obj x = obj1; //  can only be used as the template argument below because it's a compile time constant
    A<x> a;
    return 0;
}

然而,这只适用于如果你想"切换"一个编译时间常数,听起来你不。您需要使用运行时条件(ifswitch等)。

你处理问题的方法不对。模板是在编译时实例化的,因此您不能根据运行时存在的值选择专门化。除了代码中的其他错误之外,这个解决方案将不起作用。

对于这类问题(基于一个参数创建不同的对象),一个常见的解决方案是抽象工厂模式。这意味着您将条件构造逻辑移到工厂类中,并使用虚拟方法来避免在调用端编写不同的代码(因此实际上您使用了多态性)。

你必须这样做:

enum E
{
    A,
    B
};
template<E e>
struct A
{
};
template<>
struct A<E::A>
{
};
template<>
struct A<E::B>
{
};
int main()
{
    A<E::B> ab;
}