강의와 똑같이 진행했는데 링킹 에러가 발생합니다.
90
4 asked
main.cpp
#include <iostream>
#include "Storage.h"
using namespace std;
int main()
{
Storage<int> nValue(5);
Storage<double> dValue(6.7);
nValue.print();
dValue.print();
}
Storage.h
#pragma once
#include <iostream>
template <class T>
class Storage
{
private:
T m_value;
public:
Storage(T value)
{
m_value = value;
}
~Storage()
{
}
void print()
{
std::cout << m_value << std::endl;
}
};
Storage.cpp
#include "Storage.h"
template<>
void Storage<double>::print()
{
std::cout << "Double Type ";
std::cout << std::scientific << m_value << "\n";
}
현재 강의 중 8:03을 보고 있고요.
강의 중에서 영상을 봤을 땐 이렇게 하라고 교수님께서 말씀해주신듯 한데, 혹시 제가 뭘 잘못한게 있나요?
강의 상에서는 코드를 이렇게 작성한 경우, Specialization이 적용되지 않는 사례를 보여주시려고 하신듯 한데 저는 빌드가 되질 않습니다.
Answer 2
0
안녕하세요? 질문&답변 도우미 durams입니다.
저도 이전에 강의를 수강했을 때에는 빌드가 되었던 코드였던것 같은데, 지금 해보니 빌드가 되질 않네요. 아마 Visual Studio가 업데이트하면서 링커에 더 엄격한 규칙이 적용된 것이 아닐까 싶습니다.
에러문을 보면 여러 cpp파일 (정확히는 여러 Translation Unit)에서 Storage<double>::print가 정의되어서 그렇다고 나옵니다.
main.cpp에서dValue.print()할 때Storage<double>::print에 대한 정의 생성Storage.cpp에서 특수화를 통해Storage<double>::print에 대한 정의 생성
이렇게 두 개의 정의가 존재해서 링킹 에러가 난다고 해석할 수 있습니다.
해결 방법으로는 강의에서 소개된 것과같이 헤더 파일에 정의를 포함시키는 것이 일반적입니다.
0
안녕하세요, 인프런 AI 인턴입니다. 김동현님.
현재 질문하신 내용과 관련하여, C++ 템플릿을 사용한 코드에서 발생할 수 있는 몇 가지 일반적인 문제들에 대해 설명드릴 수 있을 것 같습니다.
C++에서 템플릿 클래스의 특수화(Specialization)를 사용할 때, 그 정의를 .cpp 파일에 별도로 작성하면 링커 에러가 발생할 수 있습니다. 이는 템플릿의 특성 때문인데, 템플릿 함수와 클래스의 정의는 일반적으로 헤더 파일에 위치해야 컴파일러가 여러 파일을 컴파일할 때 각 인스턴스에 대한 코드 생성을 적절하게 수행할 수 있습니다.
귀하의 경우, Storage<double> 클래스의 print 함수 특수화를 Storage.cpp 파일에 작성했지만, 이 특수화를 헤더 파일(Storage.h)로 옮기는 것이 옳습니다. 모든 템플릿 정의를 헤더 파일로 옮겨보세요.
이에 대한 관련 논의를 다룬 StackOverflow의 답변을 참고하실 수 있습니다. 이 문서에서는 C++ 템플릿 특수화가 주로 헤더 파일에 정의되어야 하는 이유와 적절한 사용 방법을 다루고 있습니다.
문제를 해결하기 위해서는 아래와 같이 Storage<double>::print의 특수화를 Storage.h 파일로 다시 옮겨주세요.
// Storage.h
#pragma once
#include <iostream>
template <class T>
class Storage
{
private:
T m_value;
public:
Storage(T value)
{
m_value = value;
}
~Storage()
{
}
void print()
{
std::cout << m_value << std::endl;
}
};
// Make sure to move the specialization to the header file
template<>
void Storage<double>::print()
{
std::cout << "Double Type ";
std::cout << std::scientific << m_value << "\n";
}
이렇게 하면, 모든 컴파일러가 템플릿 특수화에 접근할 수 있게 되어 링커 에러를 방지할 수 있게 됩니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
교재 있나요?
1
127
2
11:11 부근에 Something::temp와 Something::getValue의 앞에 &를 붙이는 이유가 뭔가요? (함수 이름은 포인터(주소)가 아닌가요?)
1
85
3
using namespace std; 선언 후에 std::를 하는 이유가 궁금합니다
1
98
2
cstr직접구현
0
111
3
BubbleSort
1
75
2
숙제 마지막 부분
1
76
2
수업할때 레퍼런스로 사용하는 도서는 어떤 도서인가요??
1
158
2
공변반환형 관련 문의 드립니다.
1
88
2
170강 유니크 포인터에대해 질문있습니다
1
78
1
섹션 5 퀴즈의 답이 이상합니다
1
82
2
이중포인터와 배열이 이해가 안됩니다.
1
151
2
5분 17~5분 34초 객체 잘림 질문
1
74
1
Resource.h 코드 알려주세요
1
70
1
char name[] 배열의 길이와 관련해 일부 궁금점이 생겨서 질문합니다
1
93
2
화면좌측 숫자 보이기
1
112
1
화면 좌측 숫자 보이기
0
65
1
처음 c++ 수강하려는데요. 비주얼스튜디오 2022 다운로드해서 설치하면 되는건가요??
1
134
3
46강 string 버퍼 질문입니다
1
79
2
프로그래머스 수열과 구간 쿼리 2 문제 질문입니다.
1
122
2
[] 범위 검사시 assert 사용 관련 질문
1
85
2
Lecture 클래스 멤버변수 명명 관련
0
86
2
프로그래머스의 대소문자 바꿔서 출력하기 문제를 푸는데요
0
67
1
noexcept과 throw()
1
78
2
explicit instantiation에 대해
1
60
2

