예제가 없으면 이해하기가 약간 까다 롭습니다. 그것을 이해하면 클래스 템플릿의 생성자를 전문화하고 다른 템플릿 인수에 대해 멤버를 다르게 구성하려고합니다. 이것이 올바르지 않으면 알려 주시면 답변을 조정하겠습니다.
다시 한번 예를 들자면 당신이하는 일이나 이해하지 못한 것을 알기가 어렵습니다. 그러나 일반적으로 이것은 다른 방법을 전문으로하는 것과 같은 방식으로 수행됩니다. 헤더의 모든 전문화를 선언하고 구현 파일에 구현하십시오 (부분 전문화가 아닌 경우). 전문화 할 때는 template<>
을 사용해야합니다. 예를 들면 다음과 같습니다.
struct t_param_for_int {};
struct t_param_for_double {};
// t_member's constructor is very different depending on T
template<class T> struct t_member {};
template<> struct t_member<int> {
explicit t_member(const t_param_for_int value) {};
};
template<> struct t_member<double> {
explicit t_member(const t_param_for_double value) {};
};
// Foo has a t_member and a constructor
template<class T>
struct foo
{
foo();
t_member<T> member;
};
// Declare specialization
template<> foo<int>::foo();
template<> foo<double>::foo();
// Specialization implementations (in a .cpp)
template<> foo<int>::foo() : member(t_param_for_int{})
{ }
// Specialization implementations (in a .cpp)
template<> foo<double>::foo() : member(t_param_for_double{})
{ }
int main()
{
foo<int> int_foo;
foo<double> dbl_foo;
return 0;
}
편집 : 질문 편집에 대한 응답입니다.
이 경우 생성자를 전문으로 설정할 수 없습니다. 가장 좋은 해결책은 헬퍼 구조체를 사용하여 실제 초기화를 수행하는 것입니다. 당신은 어떤 숫자가 0이거나 디폴트 구성 요소 인 T
으로 컨테이너를 초기화하기를 원한다고 언급했다. 그러나 컨테이너의 크기를 지정하지 않았습니다. 가짜 컨테이너 크기를 사용하여 도우미 구조체를 사용하는 방법을 보여주는 예를 만들었습니다.
#include <array>
#include <iostream>
#include <type_traits>
#include <string>
#include <utility>
#include <vector>
template<typename T, typename C>
struct helper_init;
template<typename T>
struct helper_init<T, std::vector<T>> {
static std::vector<T> init() {
return std::vector<T>(3, T{}); // init your vector with 3 elements
}
};
template<typename T>
struct helper_init<T, std::array<T, 2>> {
static std::array<T, 2> init() {
return {}; // init your array with 2 elements
}
};
template <typename T, typename C>
struct foo {
T m;
C container;
using value_type = typename C::value_type;
template <typename... Args>
foo(Args&&... args)
: m(std::forward<Args>(args)...)
, container(helper_init<T, C>::init())
{}
};
int main()
{
foo<int, std::vector<int>> vec_foo(5);
foo<std::string, std::array<std::string, 2>> str_foo("hello");
// Output to illustrate
// The size of the containers are 3 and 2 (see container initialization)
std::cout << vec_foo.container.size() << ' '
<< str_foo.container.size() << std::endl;
// The m members contain the assigned values
std::cout << vec_foo.m << " \'" << str_foo.m << '\'' << std::endl;
// The containers are zero or default initialized
std::cout << vec_foo.container.front() << " \'" <<
str_foo.container.front() << '\'' << std::endl;
return 0;
}
산술 형식을 0으로 초기화하고 클래스 형식을 기본으로 구성하는 질문의 두 번째 부분에 대해서는 언어에 이미이 기능이 있습니다.
std::array 구체적으로 말하면 건설에 대해 말합니다.
는
그런 다음 aggregate initialization이 말한다 집계 초기화의 규칙에 따라 배열을 초기화.
초기화 조항의 수는 회원 또는 초기화 목록의 수보다 작 으면
이 완전히 비어, 나머지 멤버는 값 초기화을.
마지막으로 value initialization은 이것을 말합니다.
1) T가 모든 종류의 사용자 제공 생성자가 하나 이상있는 클래스 유형 인 경우 기본 생성자가 호출됩니다.
4) 그렇지 않으면 개체가 0으로 초기화됩니다.
이렇게하면 std::array<T, 10> my_array{};
이되며 0이 지정되거나 기본값 인 T
이 생성됩니다. std::vector<T> my_vector(10, T{});
도 같은 결과를 얻을 수 있습니다 (T{}
is value constructed`).
편집 2 : [위임 생성자] 및 태그 디스 패칭을 사용하여 질문 요구 사항을보다 잘 준수하는 또 다른 솔루션이 있습니다.
#include <array>
#include <string>
#include <vector>
// Tags for supported containers
struct t_tag_array {};
struct t_tag_vector {};
// Tag dispatching
template<class T, size_t S>
struct t_container_tag {};
template<class T, size_t S>
struct t_container_tag<std::vector<T>, S> {
using type = t_tag_vector;
};
template<class T, size_t S>
struct t_container_tag<std::array<T, S>, S> {
using type = t_tag_array;
};
// Helper to fetch the size of an std::array
template<typename>
struct array_size;
template<typename T, size_t S>
struct array_size<std::array<T, S>> {
static const auto value = S;
};
template <typename C, size_t S = array_size<C>::value>
struct foo
{
using value_type = typename C::value_type;
// Constructor
template<typename... Args>
foo(Args&&... args) : foo(typename t_container_tag<C, S>::type{}, std::forward<Args>(args)...) {}
// Specialized constructor for vectors
template<typename... Args>
foo(t_tag_vector &&, Args&&... args) : m(std::forward<Args>(args)...), container(S, value_type{}) {}
// Specialized constructor for arrays
template<typename... Args>
foo(t_tag_array &&, Args&&... args) : m(std::forward<Args>(args)...), container{} {}
value_type m;
C container;
};
코드 샘플은 문제를 자세히 설명합니다. 이런 식으로 뭔가를 찾으십니까? - http://coliru.stacked-crooked.com/a/5d9ea40421963b70? – Praetorian
기회를 얻 자마자 제공 한 예를 사용하여 답변을 수정하겠습니다. –