【问题标题】:Using Template in struct in C++在 C++ 结构中使用模板
【发布时间】:2017-07-21 10:03:38
【问题描述】:

我正在学习 C++11x 中的 lambda 表达式,我用谷歌搜索了相同的内容,并在下面的代码 sn-p 中发现模板类型名用作继承。

说,

    template< class T >
    struct MyType : T {
            ....

当我编译代码时,它没有给出任何错误。但是当我尝试为 struct MyType 创建一个实例时,它导致了错误。

// Example program
#include <iostream>
#include <string>

template< class T >
struct MyType : T {
  static const auto data = 0;
  static const size_t erm = sizeof(data);
};


int main()
{
  struct MyType<int> my;
  std::cout<<"\n test ";
  return 0;
 }

编译上述代码时出错:

    In instantiation of 'struct MyType<int>': 
    15:22: required from here    
    6:8: error: base type 'int' fails to be a struct or class type In function 'int main()': 
    15:22: warning: unused variable 'my' [-Wunused-variable]

请添加一些光。为什么编译在实例化结构时会出错?另一方面,为什么声明没有给出任何错误?

提前致谢。

【问题讨论】:

  • type 参数用作您的类型的基类。 int 不是一个类,你不能从它继承。您需要另一个结构(或类)作为您的基础。我认为错误消息 base type int failed to be a struct or class 很清楚...

标签: c++ templates inheritance


【解决方案1】:

为什么编译在实例化结构时会出错?在另一 hand 为什么声明没有给出任何错误?

这是因为严格来说模板声明不是代码。只有当您使用具体的模板参数实例化它时,编译器才会将模板转换为“真实”代码。您不会在模板声明中收到错误,因为对于任何结构或类类型,您的模板都可以。只有当模板的任何模板参数格式错误时,编译器才会在您实例化它之前抱怨。例如。这个

template <typename T> 
void foo () { asdf(); }

将导致错误(前提是范围内没有asdf):

prog.cpp: In function ‘void foo()’: 
prog.cpp:5:20: error: there are no arguments to ‘asdf’ that depend on a 
template parameter, so a declaration of ‘asdf’ must be available    
[-fpermissive]  void foo () { asdf(); }

但是这个

template <typename T>
void foo() { T::asdf(); } 

不会,因为可能有一个T 会导致模板格式正确。只有当您使用没有T::asdf()T 实例化它时,您才会收到错误消息。

【讨论】:

    【解决方案2】:

    我认为编译器给出了很好的解释。简而言之,您不能从 int 这样的基本类型派生。

    声明本身:

    template< class T >
    struct MyType : T {
      static const auto data = 0;
      static const size_t erm = sizeof(data);
    };
    

    绝对有效。所以编译器不会抱怨它。

    但是当涉及到 MyType&lt;T&gt;T = int 的实例化时,编译器会尝试生成代码,一般来说,它看起来像这样:

    struct MyType : int {
      static const auto data = 0;
      static const size_t erm = sizeof(data);
    };
    

    这是无效的C++,因为MyType 试图从int 继承。

    【讨论】:

      【解决方案3】:
      • 问题是用您传递的实际类型 struct MyType&lt;int&gt; my; 替换 T 变成:

        struct MyType : int

      您可以看到为什么这是无效的。你不能从不是的东西继承。 int 是一个简单内置类型。

      这不可能的原因有很多,但在我看来,所有这些都归结为继承多态封装 em> 不适用于内置的基本类型。他们没有方法表,所以你不能覆盖它们......

      编译器已经给你一个很好的错误信息:

      clang++ 的说法可能更清楚

      test.cpp:9:17: error: base specifier must name a class
      struct MyType : T {
      

      icpc

      test.cpp(9): error: not a class or struct name
        struct MyType : T 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多