类中的模板函数

时间:2013-11-27 12:39:39

标签: c++ templates

我不知道该怎么办。我总是通过使用简单的类和简单的模板函数来获得错误。我阅读了所有其他解决方案,但他们没有帮助我。

在其他一些类旁边,我有简单的类Data:

class Data{
public:
    template <class T>
    T dat();
    int id;
    union{
        char c;
    int i;
    double d;
    };
};

和函数dat:

template <class T>
T Data::dat(){
    if(id == 1) return i;
    if(id == 2) return d;
    if(id == 3) return c;
}

如您所见,我想检查id并返回int,double或char。 现在我试图在main函数中打印这样的值:

Data test;
test.id=1;
test.i = 12;
cout<<test.dat();

但我总是收到此错误消息:

Error: Could not find a match for Data::dat<Data::T>() needed in main(int, char**).

问题在哪里?

谢谢

5 个答案:

答案 0 :(得分:4)

准确地说,你想要函数的返回类型 取决于它是对象中的id字段;换一种说法, 动态。模板在编译时解析,因此它们 在这里忍不住。你将不得不返回类似的东西 boost::variantboost::any,支持此类动态 打字。

答案 1 :(得分:1)

使用此:

cout<<test.dat<int>();

答案 2 :(得分:1)

dat()没有涉及T的参数,因此编译器无法从调用中推断出T,并且必须明确提供,例如:

cout << test.dat<int>();

另外,请记住,您必须implement dat() in the header file

答案 3 :(得分:1)

  

我不知道该怎么办。我总是通过使用简单的类和简单的模板函数来获得错误。我阅读了所有其他解决方案,但他们没有帮助我。

在我看来,你想创造一个有区别的联盟。

您的实现不起作用,因为模板函数的返回类型是在编译时确定的(即在您在id中设置值并尝试调用该函数之前。

解决方案:

class Data
{
    enum value_type {
        int_val, char_val, double_val
    } discriminator; // private (the user doesn't see this)
                     // this replaces your id

    union{
        char c;
        int i;
        double d;
    } value;

public:
    class wrong_type_error: public std::logic_error
    {
    public:
        wrong_type_error(const std::string& msg): std::logic_error(msg) {}
    };

    explicit Data(const char c)
    : discriminator(Data::char_value)
    , value.c(c)
    {
    }

    explicit Data(const int i)
    : discriminator(Data::int_value)
    , value.i(i)
    {
    }

    explicit Data(const double d)
    : discriminator(Data::double_value)
    , value.d(d)
    {
    }

    // don't put this here: int id;

    // this part can be optimized to simpler (more idiomatic) code
    template<typename T> T get() const; // undefined
    template<> int get() const {
        if(discriminator != Data::int_val)
            throw wrong_type_error("Cannot return a int from Data instance");
        return value.i;
    }
    template<> char get() const {
        if(discriminator != Data::char_val)
            throw wrong_type_error("Cannot return a char from Data instance");
        return value.c;
    }
    template<> double get() const {
        if(discriminator != Data::double_val)
            throw wrong_type_error("Cannot return a double from Data instance");
        return value.d;
    }
};

客户代码:

Data test(10.5);
cout<<test.get<double>();

所有这一切,您应该考虑使用boost :: variant或boost :: any实例,具体取决于您的需求。

答案 4 :(得分:0)

VS2012说 “错误C2783:'T Data :: dat(void)':无法推断'T'的模板参数”

您只需告诉函数dat T是什么:

cout<<test.dat<int>();

如果传递模板化参数,可以推导出模板类型,但它可以猜测返回类型。