템플릿 유형의 올바른 생성자를 호출하는 방법은 무엇입니까?


21

다음 코드에서 주석 처리 된 줄을 바로 위의 줄과 동일한 방식으로 작동하게하려면 어떻게해야합니까?

적절한 코드 생성자를 호출하는 일반 코드로 만들고 싶습니다 Type.

#include <string>
#include <iostream>

template <typename Type>
struct Class
{
    Type data;
    Class(Type data) : data(data) { }
};

int main()
{
    Class<std::string> a = std::string("abc");
    // Class<std::string> b = "abc";
    std::cout << a.data << std::endl;
    return 0;
}

답변:


14

직접 초기화를 사용하십시오.

Class<std::string> b("abc");

17

사용 보강-초기화 목록 (또는 균일 개시가)의 인스턴스를 initlize하기 Class.

Class<std::string> a{ std::string("abc") };  // works
Class<std::string> b{ "abc" };               // also works

13
Class<std::string> b = "abc";

이다 복사 초기화 . 두 가지 사용자 정의 변환이 포함되므로 작동하지 않습니다.

  • 에서 const char*std::string,
  • 에서 std::string까지 Class<std::string>.

그러나 최대 하나만 허용됩니다.

당신이 쓸 때

Class<std::string> b("abc");
// or
Class<std::string> b{"abc"};

직접 초기화 를 사용 합니다. 이제 하나의 사용자 정의 변환 만 사용되기 때문에 작동합니다.

  • 에서 const char*까지 std::string.

0

을 변경할 수 있으면 Class템플릿 변환 생성자를 추가 할 수 있습니다. 그런 다음 예제에 작성된대로 주석 처리 된 행을 컴파일 할 수 있습니다. 그러나 일반적으로 적절한 이유없이 암시 적 변환을 사용하지 않는 것이 좋습니다 (스팟 찾기 어려운 버그가 발생할 수 있음 ( C ++ 핵심 지침 ) 참조 ).

#include <string>
#include <iostream>

template <typename Type>
struct Class
{
    Type data;
    Class(Type data) : data(data) { }

    template<typename Other>
    Class(Other other_data) : data(other_data) {}
};


int main()
{
    Class<std::string> a = std::string("abc");
    Class<std::string> b = "abc";
    Class<std::string> c = a;

    std::cout << b.data << std::endl;
    return 0;
}

C ++ 14를 사용할 수 있으면 std::literals::string_literals::operator""s변환 생성자를 사용 하고 제거 할 수 있습니다 . 그런 다음 줄은 다음과 같습니다.

using namespace std::literals;

Class<std::string> b = "abc"s;

여기에 라이브 코드가 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.