使函数模板专业化虚拟合法吗?

发布于 2024-07-16 23:34:07 字数 602 浏览 9 评论 0原文

在 C++ 中,函数模板特化的行为应该与普通函数完全相同。 这是否意味着我可以制作一个虚拟的?

例如:

struct A
{
    template <class T> void f();
    template <> virtual void f<int>() {}
};

struct B : A
{
    template <class T> void f();
    template <> virtual void f<int>() {}
};

int main(int argc, char* argv[])
{
    B b;
    A& a = b;
    a.f<int>();
}

Visual Studio 2005 给出以下错误:

致命错误 C1001:编译器中发生内部错误。

In C++, a function template specialization is supposed to act exactly like a normal function. Does that mean that I can make one virtual?

For example:

struct A
{
    template <class T> void f();
    template <> virtual void f<int>() {}
};

struct B : A
{
    template <class T> void f();
    template <> virtual void f<int>() {}
};

int main(int argc, char* argv[])
{
    B b;
    A& a = b;
    a.f<int>();
}

Visual Studio 2005 gives me the following error:

fatal error C1001: An internal error has occurred in the compiler.

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

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

发布评论

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

评论(3

弥繁 2024-07-23 23:34:07

不错的编译器错误。 对于这种类型的检查,我总是先使用 Comeau 编译器,然后再返回标准并进行检查。

Comeau C/C++ 4.3.10.1(2008 年 10 月 6 日)
11:28:09) ONLINE_EVALUATION_BETA2
版权所有 1988-2008 ComeauComputing。
版权所有。 模式:严格
错误 C++ C++0x_extensions

“ComeauTest.c”,第 3 行:错误:
函数中不允许使用“virtual”
模板
宣言
模板 virtual void f();
^

“ComeauTest.c”,第 10 行:错误:
函数中不允许使用“virtual”
模板
宣言
模板 virtual void f();
^

现在,正如另一位用户所发布的那样,事实是该标准不允许您定义虚拟模板化方法。 基本原理是,对于所有虚拟方法,必须在 vtable 中保留一个条目。 问题是模板方法只有在实例化(使用)时才会被定义。 这意味着 vtable 最终在每个编译单元中将具有不同数量的元素,具体取决于发生了多少次对不同类型的 f() 的不同调用。 那么地狱就会出现...

如果您想要的是其参数之一的模板化函数,并且一个特定版本是虚拟的(请注意参数的部分),您可以这样做:

class Base
{
public:
   template <typename T> void f( T a ) {}
   virtual void f( int a ) { std::cout << "base" << std::endl; }
};
class Derived : public Base
{
public:
   virtual void f( int a ) { std::cout << "derived" << std::endl; }
};
int main()
{
   Derived d;
   Base& b = d;
   b.f( 5 ); // The compiler will prefer the non-templated method and print "derived"
}

如果您希望将此泛化为任何类型,那么你运气不好。 考虑另一种类型的委托而不是多态(聚合+委托可能是一个解决方案)。 有关当前问题的更多信息将有助于确定解决方案。

Nice compiler error. For this type of checks I always fallback to the Comeau compiler before going back to the standard and checking.

Comeau C/C++ 4.3.10.1 (Oct 6 2008
11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.
All rights reserved. MODE:strict
errors C++ C++0x_extensions

"ComeauTest.c", line 3: error:
"virtual" is not allowed in a function
template
declaration
template virtual void f();
^

"ComeauTest.c", line 10: error:
"virtual" is not allowed in a function
template
declaration
template virtual void f();
^

Now, as it has been posted by another user, the fact is that the standard does not allow you to define virtual templated methods. The rationale is that for all virtual methods, an entry must be reserved in the vtable. The problem is that template methods will only be defined when they have been instantiated (used). This means that the vtable would end up having a different number of elements in each compilation unit, depending on how many different calls to f() with different types happen. Then hell would be raised...

If what you want is a templated function on one of its arguments and one specific version being virtual (note the part of the argument) you can do it:

class Base
{
public:
   template <typename T> void f( T a ) {}
   virtual void f( int a ) { std::cout << "base" << std::endl; }
};
class Derived : public Base
{
public:
   virtual void f( int a ) { std::cout << "derived" << std::endl; }
};
int main()
{
   Derived d;
   Base& b = d;
   b.f( 5 ); // The compiler will prefer the non-templated method and print "derived"
}

If you want this generalized for any type, then you are out of luck. Consider another type of delegation instead of polymorphism (aggregation + delegation could be a solution). More information on the problem at hand would help in determining a solution.

我只土不豪 2024-07-23 23:34:07

根据 http://www.kuzbass.ru:8086/docs/isocpp/ template.html ISO/IEC 14882:1998:

-3- 成员函数模板不应是虚拟的。

例子:

template <class T> struct AA {
    template <class C> virtual void g(C);   //  Error
    virtual void f();                       //  OK
};

According to http://www.kuzbass.ru:8086/docs/isocpp/template.html ISO/IEC 14882:1998:

-3- A member function template shall not be virtual.

Example:

template <class T> struct AA {
    template <class C> virtual void g(C);   //  Error
    virtual void f();                       //  OK
};
孤城病女 2024-07-23 23:34:07

正如其他人所指出的,这不是合法代码,因为成员函数模板不能声明为虚拟的。

然而,即使是 Visual Studio 2012 也对此感到窒息:
Visual Studio 2012 上的 C++ 内部编译器错误
单击此处查看完整尺寸

事件日志表明编译器崩溃于0xC0000005,或STATUS_ACCESS_VIOLATION。 有趣的是,某种(非法)代码构造如何使编译器出现段错误......

As others have noted, this is not legal code because a member function template cannot be declared virtual.

Yet even Visual Studio 2012 chokes on this:
C++ internal compiler error on Visual Studio 2012
Click here for full size

Event logs indicate that the compiler crashed on 0xC0000005, or STATUS_ACCESS_VIOLATION. It's funny how a certain (illegal) code construct can make the compiler segfault...

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