인프런 커뮤니티 질문&답변
강의와 똑같이 진행했는데 링킹 에러가 발생합니다.
작성
·
23
1
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이 적용되지 않는 사례를 보여주시려고 하신듯 한데 저는 빌드가 되질 않습니다.
답변 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";
}
이렇게 하면, 모든 컴파일러가 템플릿 특수화에 접근할 수 있게 되어 링커 에러를 방지할 수 있게 됩니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.





