实例化C++;不带参数/取决于if语句中的类型的模板类 < >我在C++中编写了不同的函数对象A、B和C,并且我想根据用户输入实例化一个具有函数对象的模板类。但似乎没有办法只实例化if语句中的一种类型,是吗

实例化C++;不带参数/取决于if语句中的类型的模板类 < >我在C++中编写了不同的函数对象A、B和C,并且我想根据用户输入实例化一个具有函数对象的模板类。但似乎没有办法只实例化if语句中的一种类型,是吗,c++,c++11,g++,C++,C++11,G++,如果我试图在If语句中用模板实例化一个类,g++编译器会给我一个“使用未声明的标识符'bkt'”-错误。如果我事先实例化了它,那么类在离开If语句时会破坏自身 这是我的密码: class A { public: void operator()(int a) {} }; class B { public: void operator()(int a) {} }; class C { public: void operator()(int a) {} }; template <ty

如果我试图在If语句中用模板实例化一个类,g++编译器会给我一个“使用未声明的标识符'bkt'”-错误。如果我事先实例化了它,那么类在离开If语句时会破坏自身

这是我的密码:

class A {
public: void operator()(int a) {}
}; 

class B {
public: void operator()(int a) {}
}; 

class C {
public: void operator()(int a) {}
}; 

template <typename T>
class MyClass {
public:
  MyClass<T>(const std::string &file);
  ~MyClass<T>;

private:
  T m_func;

int doStuff(int a) {
  return m_func(a);
 }
};

int main() {

std::string filename = std::string(argv[1]);
std::getline(std::cin, metric);

if (metric == "A") {
  MyClass<A> foo(filename);
}
else if (metric == "B") {
  MyClass<B> foo(filename);
}
else {
  MyClass<C> foo(filename);
}

int a = 1;
foo.doStuff(int a); // undeclared identifier "foo"

getchar();
return 0;
}
A类{
public:void运算符()(int a){}
}; 
B类{
public:void运算符()(int a){}
}; 
C类{
public:void运算符()(int a){}
}; 
模板
类MyClass{
公众:
MyClass(const std::string和file);
~MyClass;
私人:
T m_func;
内塔塔夫(内塔){
返回m_func(a);
}
};
int main(){
std::string filename=std::string(argv[1]);
std::getline(std::cin,公制);
如果(度量=“A”){
MyClass foo(文件名);
}
否则如果(度量=“B”){
MyClass foo(文件名);
}
否则{
MyClass foo(文件名);
}
INTA=1;
foo.doStuff(int a);//未声明的标识符“foo”
getchar();
返回0;
}

我知道,我必须以某种方式声明foo变量,但我希望编译器可以接受它,因为if语句的一种情况无论如何都会发生。显然不是这样,那么我该怎么做才能不实例化每一种类型呢?

简单来说:模板可以帮助您实现编译时多态性,但您需要的是运行时多态性。然而,将它们混合起来是很简单的

首先创建一个基类:

struct MyBase {
    ~MyBase(){}
    virtual int doStuff(int a) = 0;
};
然后让模板化类从中继承:

template <typename T>
class MyClass : MyBase {
public:
   MyClass<T>(const std::string &file);
   ~MyClass<T>;    
private:
   T m_func;
int doStuff(int a) override {
  return m_func(a);
 }
};
为了完整性…您的代码不起作用,因为

if (metric == "A") {
  MyClass<A> foo(filename);
}
if(度量==“A”){
MyClass foo(文件名);
}
foo
的生存期仅限于以
}
结尾的
if
案例的范围,您不能在外部访问它

PS:由于所有指标都具有相同的特征,我会使用不同的方法,不需要将
MyClass
作为模板。无论如何,
MyClass
作为模板似乎是一项要求

PPS:也许这只是一个措辞问题,但是

那么,为了不实例化每一种类型,我可以做些什么呢


你对此无能为力。模板在编译时实例化。如果您想在运行时选择一个实例化,您需要将它们实例化。在上面的代码中(一旦你填补了漏洞),每个可能的度量都会有一个实例化,但它只创建了一个实例。

简单来说:模板可以帮助你实现编译时多态性,但你需要的是运行时多态性。然而,将它们混合起来是很简单的

首先创建一个基类:

struct MyBase {
    ~MyBase(){}
    virtual int doStuff(int a) = 0;
};
然后让模板化类从中继承:

template <typename T>
class MyClass : MyBase {
public:
   MyClass<T>(const std::string &file);
   ~MyClass<T>;    
private:
   T m_func;
int doStuff(int a) override {
  return m_func(a);
 }
};
为了完整性…您的代码不起作用,因为

if (metric == "A") {
  MyClass<A> foo(filename);
}
if(度量==“A”){
MyClass foo(文件名);
}
foo
的生存期仅限于以
}
结尾的
if
案例的范围,您不能在外部访问它

PS:由于所有指标都具有相同的特征,我会使用不同的方法,不需要将
MyClass
作为模板。无论如何,
MyClass
作为模板似乎是一项要求

PPS:也许这只是一个措辞问题,但是

那么,为了不实例化每一种类型,我可以做些什么呢


你对此无能为力。模板在编译时实例化。如果您想在运行时选择一个实例化,您需要将它们实例化。在上面的代码中(一旦填补了漏洞),每个可能的度量都会有一个实例化,但只创建了一个实例。

它真的必须是模板参数吗?您的不同度量似乎都是同一类型的,这仅仅是因为示例的简化吗?如果没有,我建议删除模板。在运行时选择一个tempalte实例化并不是tempaltes真正的亮点。模板必须在编译时实例化,因为太草率了,它们当然不是同一类型的,但是简单的重构可以使它们成为同一类型的模板,而使用tempalte需要更多的努力,您可以声明
int a=1在度量评估之前,然后调用
foo.doStuff(a)if
语句中的code>(我知道这是代码重复,但如果不进行重构,我就看不到其他方法了)。注意:您必须在
foo.doStuff()
调用中给出
a
而不是
int a
。@formerlyknownas_463035818使用模板是要求的一部分。annd是的,函数实际上做了非常不同的事情(它是用于自动更正的字符串度量()的声明)…它真的必须是模板参数吗?您的不同度量似乎都是同一类型的,这仅仅是因为示例的简化吗?如果没有,我建议删除模板。在运行时选择一个tempalte实例化并不是tempaltes真正的亮点。模板必须在编译时实例化,因为太草率了,它们当然不是同一类型的,但是简单的重构可以使它们成为同一类型的模板,而使用tempalte需要更多的努力,您可以声明
int a=1在度量评估之前,然后调用
foo.doStuff(a)if
语句中的code>(我知道这是代码重复,但如果不进行重构,我就看不到其他方法了)。注意:您必须在
foo.doStuff()
调用中给出
a
而不是
int a
。@formerlyknownas_463035818使用模板是要求的一部分。annd是的,函数实际上做了非常不同的事情(它是