Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无法实例化抽象类:为什么模板参数(引用)会导致这种情况?_C++_Templates_Abstract - Fatal编程技术网

C++ 无法实例化抽象类:为什么模板参数(引用)会导致这种情况?

C++ 无法实例化抽象类:为什么模板参数(引用)会导致这种情况?,c++,templates,abstract,C++,Templates,Abstract,我在一些代码方面遇到了问题 “Bar”:无法实例化抽象类 我终于能够用少量代码重新创建错误 struct SomeStruct { // ****** }; template <typename TIN, typename TOUT, typename TINDEX> struct IFoo { public: virtual void add(const TIN item) = 0; // <-- BAD //virtual void add(con

我在一些代码方面遇到了问题

“Bar”:无法实例化抽象类

我终于能够用少量代码重新创建错误

struct SomeStruct
{
    // ******
};

template <typename TIN, typename TOUT, typename TINDEX>
struct IFoo
{
public:
    virtual void add(const TIN item) = 0; // <-- BAD
    //virtual void add(const TOUT& item) = 0; // <-- GOOD

    // ******
};

template <typename TVALUE, typename TINDEX>
struct Bar : IFoo<TVALUE &, TVALUE, TINDEX>
{

public:

    void add(const TVALUE& item)
    {
        // ******
    }

    // ******
};

int main(int argc, char *argv[])
{
    SomeStruct someStruct;
    Bar<SomeStruct, int> bar = Bar<SomeStruct, int>();
    bar.add(someStruct);

    // ******
}

有人能告诉我们为什么使用模板参数引用会导致这种情况吗?

您的问题可以追溯到函数签名等基本概念:函数签名/原型由函数名称、参数数量、参数数据类型以及这些参数的出现顺序给出

对于任何两个函数,如果上述任何一个函数不同,则表示您正在处理两个不同的函数

更确切地说,这两个代表两个不同的签名:

virtual void add(const TIN item) = 0; 
virtual void add(const TOUT& item) = 0;

由于您只在派生类中实现了第二个,因此会出现错误。

您的问题可以追溯到函数签名等基本概念:函数签名/原型由函数名、参数数量、参数的数据类型以及这些参数的出现顺序给出

对于任何两个函数,如果上述任何一个函数不同,则表示您正在处理两个不同的函数

更确切地说,这两个代表两个不同的签名:

virtual void add(const TIN item) = 0; 
virtual void add(const TOUT& item) = 0;

由于您只在派生类中实现了第二个,因此会出现错误。

我们可以简单地将您的示例进一步扩展到:

template <typename T>
struct IFoo {
    virtual void add(const T item) = 0;
};

template <typename T>
struct Bar : IFoo<T&> {
    void add(const T& item) { }
};

我们可以将您的示例进一步简化为:

template <typename T>
struct IFoo {
    virtual void add(const T item) = 0;
};

template <typename T>
struct Bar : IFoo<T&> {
    void add(const T& item) { }
};

这里的问题是,当您编写const TIN并且TIN是引用类型时,const应用于引用而不是值类型

这就是为什么你会看到const TIN和const TOUT的不同行为&即使你认为他们应该是一样的

解决此问题的一个简单方法是在IFoo实例化中将const添加到值类型中:

struct Bar : IFoo<const TVALUE &, TVALUE, TINDEX>
//          here  ^^^^

这里的问题是,当您编写const TIN并且TIN是引用类型时,const应用于引用而不是值类型

这就是为什么你会看到const TIN和const TOUT的不同行为&即使你认为他们应该是一样的

解决此问题的一个简单方法是在IFoo实例化中将const添加到值类型中:

struct Bar : IFoo<const TVALUE &, TVALUE, TINDEX>
//          here  ^^^^

因为您是在Bar addconst TVALUE&中实现的,带有引用。这是一个不同于在基类中声明为纯虚拟的函数的函数。通过修改Bar中的定义来撤销addconst TVALUE&item override,您将看到@Hcorg所说的是正确的;编译器会告诉您,您没有重写基类中的函数。这不是问题所在,因为TIN是&。因为您是在带引用的Bar addconst TVALUE&中实现的。这是一个不同于在基类中声明为纯虚拟的函数的函数。通过修改Bar中的定义来撤销addconst TVALUE&item override,您将看到@Hcorg所说的是正确的;编译器会告诉您,您没有重写基类中的函数。这不是问题所在,因为TIN是TOUT&@bikie:If TIN==TOUT&,const TIN仍然不同于const TOUT&。在这种情况下,const-TIN仍然只是TOUT&,这与const-TOUT&不同。第一个函数接受TIN类型的变量作为参数,第二个函数接受对变量的引用。因此,即使是TIN和TOUT都是相同的数据类型,引用类型和变量也不相同thing@Beakie:如果TIN==TOUT&,则const TIN仍然不同于const TOUT&。在这种情况下,const-TIN仍然只是TOUT&,这与const-TOUT&不同。第一个函数接受TIN类型的变量作为参数,第二个函数接受对变量的引用。所以即使是TIN和TOUT都是相同的数据类型,引用类型和变量也不是一回事