【问题标题】:C++ Class template: "Required from here" errorC++ 类模板:“从这里需要”错误
【发布时间】:2021-08-14 06:49:38
【问题描述】:

我正在学习 C++ 类模板。下面是我的代码。当我运行它时,我收到“从这里需要”的错误。如果有人能指出这个问题,那将是很大的帮助。错误行号对应frank对象的实例化。

#include <iostream>
#include <string>

template <typename T>               
class Data
{
private:
                                       
    std::string name;
    T value; 
public:
    Data(std::string n, T v) : value {v}, name {n}
    {
        
    }
    ~Data() = default; 
    
    T getValue()
    {
        return value;
    }
    std::string getName()
    {
        return name;
    }
};

int main()
{
    Data<int> frank {"frank", 35};                                 
    
    std::cout << std::endl;
}

添加构建日志:

C:\WINDOWS\system32\cmd.exe /C mingw32-make.exe -j 8 -e -f  Makefile
"----------Building project:[ TestArea - Debug ]----------"
mingw32-make.exe[1]: Entering directory 'C:/Users/LPC/Documents/C_Plus_Plus/TestArea'
mingw32-make.exe[1]: Leaving directory 'C:/Users/LPC/Documents/C_Plus_Plus/TestArea'
mingw32-make.exe[1]: Entering directory 'C:/Users/LPC/Documents/C_Plus_Plus/TestArea'
g++  -c  "C:/Users/LPC/Documents/C_Plus_Plus/TestArea/main.cpp" -g -O0 -std=c++14 -Wall  -o ./Debug/main.cpp.o -I. -I.
C:/Users/LPC/Documents/C_Plus_Plus/TestArea/main.cpp: In instantiation of 'Data<T>::Data(std::__cxx11::string, T) [with T = int; std::__cxx11::string = std::__cxx11::basic_string<char>]':
C:/Users/LPC/Documents/C_Plus_Plus/TestArea/main.cpp:30:33:   required from here
C:/Users/LPC/Documents/C_Plus_Plus/TestArea/main.cpp:10:7: warning: 'Data<int>::value' will be initialized after [-Wreorder]
     T value;
       ^
C:/Users/LPC/Documents/C_Plus_Plus/TestArea/main.cpp:9:17: warning:   'std::__cxx11::string Data<int>::name' [-Wreorder]
     std::string name;
                 ^
C:/Users/LPC/Documents/C_Plus_Plus/TestArea/main.cpp:12:5: warning:   when initialized here [-Wreorder]
     Data(std::string n, T v) : value {v}, name {n}
     ^
g++ -o ./Debug/TestArea @"TestArea.txt" -L.
mingw32-make.exe[1]: Leaving directory 'C:/Users/LPC/Documents/C_Plus_Plus/TestArea'
====1 errors, 3 warnings====

【问题讨论】:

  • 这只是跨越多行的警告消息的一部分。相关部分是“警告:Data&lt;int&gt;::value将在std::string Data&lt;int&gt;::name之后初始化”。
  • 请将整组编译器消息复制并粘贴为文本。图片没用。
  • 这似乎是说你的成员变量的声明顺序和你的构造函数初始化列表的顺序不匹配。变量将按照声明的顺序进行初始化,而不是列表的顺序。它也看起来像一个警告,而不是一个错误。将其视为文本会更容易。 godbolt.org/z/MdrbcKGxT
  • 我没有看到实际错误。也许修复警告,看看会发生什么。我复制/粘贴了你的代码,它编译得很好。

标签: c++ class-template


【解决方案1】:

与模板无关。

警告在这里是因为程序员经常(错误地)假设

: value {v}, name {n}`

表示valuename 之前初始化。实际上初始化顺序与声明顺序一致:

std::string name;
T value; 

初始化顺序在您的情况下并不重要,但它经常很重要。因此,避免意外并使初始化程序出现的顺序始终与声明顺序相匹配通常是一个好习惯。所以就这样做吧。

【讨论】:

  • 赞成加入关于我们程序员假设事情的部分,以及关于有些情况确实很重要的事实。
【解决方案2】:

要解决警告,而不是错误,请在构造函数中切换初始化列表的顺序。

template <typename T>               
class Data
{
  private:                                     
    std::string name; // <--- Here you define name first.
    T value; 
  public:
    Data(const std::string& n, const T& v) : name {n}, value {v} // <---
                                             // This means here name will be 
                                             // initialized first as it first appears 
                                             // in the memory model of your class.
    {
        
    }
};

【讨论】:

  • 虽然你已经暗示过了,但可能值得强调的是这不是一个错误。 =)
  • 确实是一个警告,代码会以任何方式进行。
  • 与问题没有真正的关系,但考虑将 std::string 作为 const std::string& 并将 T 作为 const T& 传递。这将有助于提高性能,并且您将保证不会更改代码主体中 n 和 v 的值
  • @pepijn 确实会在示例中添加它
猜你喜欢
  • 1970-01-01
  • 2020-05-20
  • 1970-01-01
  • 2021-12-05
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-14
相关资源
最近更新 更多