vc++ 컴파일에러::C2244 질문입니다~~

dkwkekzz의 이미지

안녕하세요

초보가 질문드립니다.

template< typename T >
class Character_ptr{
public:
template< typename U >
void swap(Character_ptr< U >&& _other)
{
std::swap(ptr, _other.ptr);
std::swap(pControlBlock, _other.pControlBlock);
}
//...

swap의 구현을 cpp로 따로 빼고싶습니다.

template< typename T >
class Character_ptr{
public:
template< typename U >
void swap(Character_ptr< U >&& _other);
//...
===================================================================
template< typename T, typename U >
void Character_ptr< T >::swap(Character_ptr< U >&& _other){
std::swap(ptr, _other.ptr);
std::swap(pControlBlock, _other.pControlBlock);
}

기존에 있던 지식과 충돌이 생깁니다. 질문대로 이는 선언과 정의가 다르다며 컴파일에러가 납니다. 정확하게 일치하는데도요.

무슨 문제가 있는지 알려주십시오 ㅜㅜ

감사합니다

Anti-Lock의 이미지

간단하게 이야기해서...
템플릿 구현과 정의를 분리하는 것을 vc 컴파일러가 지원하지 않는것 아닙니까?
제가 알기로 이것을 지원하는 컴파일러는 아직 없는것으로 알고 있습니다. <-- 현재는 사실이 아닐수도 있습니다

 의 이미지

#include <iostream>
using namespace std;
 
template <typename T1>
class C{
public:
	template <typename T2>
	void mf(T1 t1, T2 t2); // 여기서 선언하고
};
 
template <typename T1> // 이렇게,
template <typename T2> // 두 번에 걸쳐서.
void C<T1>::mf(T1 t1, T2 t2){ // 여기서 정의.
	cout << t1 << " " << t2 << endl;
}
 
int main(void){
	C<int> c;
	c.mf<int>(1,2);
	return 0;
}

C++03 문법에서 허용하고, (적당히 오래된) g++ 4.4.7에서도 무사히 컴파일됩니다. VC++ 2015에서도 무사히 컴파일되고요.
그 이전 버전의 컴파일러들은 설치해 놓은 게 없는데, 언제 기준으로 지원하는 컴파일러가 없었다는 건지 저도 무척 궁금합니다.

위와 같이 한 파일 안에서 템플릿 함수의 선언과 정의를 분리하는 것뿐만 아니라, 아예 파일을 나눠서 작성할 수도 있습니다.
근데 조금 더 번거롭습니다. 이 경우에 template instantiation이 자동으로 이루어질 수 없기 때문에, 수동으로 해 줘야 하기 때문이지요.

// C.hpp
template <typename T1>
class C {
public:
	template <typename T2>
	void mf(T1 t1, T2 t2); // 선언만 하고,
};

// C.cpp
#include <iostream>
#include "C.hpp"
using namespace std;
 
template <typename T1>
template <typename T2>
void C<T1>::mf(T1 t1, T2 t2) { // 정의는 여기서
	cout << t1 << " " << t2 << endl;
}
 
// 단, 여기서 명시적으로 instantiation 해 주어야 합니다. (explicit instantiation)
// 안 그러면 링커가 mf 정의 없다고 화냄.
template void C<int>::mf<int>(int, int); // 이렇게 말이죠.

// main.cpp
#include "C.hpp"
 
int main(void) {
	C<int> c; // 아무 문제 없이 사용 가능
	c.mf<int>(1, 2); // 마찬가지
	return 0;
}
Anti-Lock의 이미지

잘 모르고 글을 올린점을 인정합니다.
제 글의 의미는 템플릿 코드를 소스파일과 헤더파일에 분리하여 기술하는것을 의미하는것이었습니다.
그리고 템플릿클래스 헤더파일과 컴파일된 템플릿클래스 오브젝트파일만을 가졌을때, 별문제없이 사용가능하지 않을것이다라는 의미였습니다.
다시말하면 템플릿코드가 들어있는 라이브러리 파일(.lib)이 가능하냐...에서 컴파일러가 지원안한다고 이야기한것입니다.
저의 의견이 사실과 다를지도 모릅니다.
템플릿으로 구성된 STL 라이브러리도 별도의 .lib안에 코드가 있는게 아니라 헤더파일에 구현되어 있음을 근거로한 저의 추측이었습니다.
이부분은 원 질문자님의 질문 내용과 크게 관련없는 부분이긴 합니다.

dkwkekzz의 이미지

오, 일단 좋은 답변 감사드립니다.

임의의 클래스에 있는 함수에 또 다른 템플릿을 씌울 때, template에 2개 인수를 넣는 줄 알고 있었는데
두 개로 구분지어야 하는군요.
정말 감사합니다.

추가적으로 하나 더 궁금한 것이 있다면 효율성입니다.

작성하면서 std안의 shared_ptr을 참고했었는데 여기는 선언과 동시에 구현이 되어 있습니다.
구현을 분리하면 컴파일 의존성을 가능한 피할 수 있다라고 알고 있는데,

std에 이렇게 구현된 의미를 알 수 있을까요?

Anti-Lock의 이미지

제대로 모르고 답변할까봐 겁이나긴하지만,,
c++에서는... 구현을 컴파일하면 오히려 컴파일러 의존성이 높아집니다. (정확한 용어의 사용은 아닙니다)
네임 맹글링 체계가 컴파일러마다 다를수 있고, 같다 할지라도 컴파일러마다 구현된 c++ 표준 버전이 다를수 있습니다.
단순히 이야기하자면, 소스코드 보다 의존성이 덜한 것은 없지 않을까요?
소스코드는 CPU, OS 등도 고려해서 설계 가능하니까요.
컴파일된 코드는 특정 CPU (혹은 OS) 에 종속되어 버립니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.