[英]Using a class with a constructor as a type parameter in a template instantiation in c++
在 C++ (14) 中,我有一個類型為 T 的模板類,我想使用一個類作為類型。 我想用於該類型的類在其構造函數中需要一個參數......那么我如何通過模板實例化傳遞這個參數?
我的示例代碼(template_hell.cpp):
#include <iostream>
template <typename T>
class my_template
{
public:
struct Stored_Data_Type
{
T data;
int set_count = 0;
};
my_template() : m_data() {};
T& write()
{
m_data.set_count++;
return m_data.data;
}
const T& get() const {return m_data.data;}
private:
Stored_Data_Type m_data;
};
class a_class
{
public:
a_class(int init): m_data(init) {};
void set(const int data) {m_data = data;};
const int get() const {return m_data;};
private:
int m_data;
};
class b_class : public a_class
{
public:
b_class(): a_class{0} {};
};
int main()
{
//a_class b(1);
b_class b;
b.set(2);
std::cout << "b: " << b.get() << std::endl;
my_template<int> my_int;
my_int.write() = 10;
std::cout << "my_int: " << my_int.get() << std::endl;
my_template<b_class> my_b;
my_b.write().set(2);
std::cout << "my_b: " << my_b.get().get() << std::endl;
// Compile error here:
my_template<a_class> my_a;
my_a.write().set(3);
std::cout << "my_a: " << my_a.get().get() << std::endl;
}
在我添加my_a
模板實例之前,這一切正常並且很好。 然后我得到這個編譯錯誤:
template_hell.cpp: In instantiation of 'my_template<T>::my_template() [with T = a_class]':
template_hell.cpp:62:24: required from here
template_hell.cpp:13:26: error: use of deleted function 'my_template<a_class>::Stored_Data_Type::Stored_Data_Type()'
my_template() : m_data() {};
^
template_hell.cpp:7:10: note: 'my_template<a_class>::Stored_Data_Type::Stored_Data_Type()' is implicitly deleted because the default definition would be ill-formed:
struct Stored_Data_Type
^~~~~~~~~~~~~~~~
template_hell.cpp:7:10: error: no matching function for call to 'a_class::a_class()'
template_hell.cpp:31:3: note: candidate: a_class::a_class(int)
a_class(int init): m_data(init) {};
^~~~~~~
template_hell.cpp:31:3: note: candidate expects 1 argument, 0 provided
template_hell.cpp:27:7: note: candidate: constexpr a_class::a_class(const a_class&)
class a_class
^~~~~~~
template_hell.cpp:27:7: note: candidate expects 1 argument, 0 provided
template_hell.cpp:27:7: note: candidate: constexpr a_class::a_class(a_class&&)
template_hell.cpp:27:7: note: candidate expects 1 argument, 0 provided
如何通過模板實例將參數傳遞給 a_class? 這不可能嗎?
您將a_class
作為模板參數傳遞給my_template
模板類,並且由於在my_template
類中Stored_Data_Type m_data;
是以下struct
的對象
struct Stored_Data_Type {
a_class data;
int set_count = 0;
};
m_data
成員默認構造為
my_template() : m_data() {}
它試圖調用您尚未定義的a_class
的默認構造函數。
因此,您只需要為a_class
類定義默認構造函數:
class a_class {
public:
a_class()
: m_data{0}
{}
// ...
};
檢查實時示例
您可以使用 Variadic 參數。 請參閱https://en.cppreference.com/w/cpp/language/parameter_pack 。 這讓我們對任何參數的轉發StoredDataType
傳遞給我們的my_template
類
可變模板允許我們以類型安全的方式編寫接受任意數量參數的類/方法,並在編譯時而不是運行時解決所有參數處理邏輯
#include <iostream>
template <typename T>
class my_template
{
public:
struct Stored_Data_Type
{
template<typename... TArgs>
Stored_Data_Type(TArgs&&... args) : data(std::forward<TArgs>(args)...)
{
}
T data;
int set_count = 0;
};
template<typename... TArgs>
my_template(TArgs&&... args) : m_data(std::forward<TArgs>(args)...) {}
T& write()
{
m_data.set_count++;
return m_data.data;
}
const T& get() const {return m_data.data;}
private:
Stored_Data_Type m_data;
};
class a_class
{
public:
a_class(int init): m_data(init) {};
void set(const int data) {m_data = data;};
const int get() const {return m_data;};
private:
int m_data;
};
class b_class : public a_class
{
public:
b_class(): a_class{0} {};
};
int main()
{
//a_class b(1);
b_class b;
b.set(2);
std::cout << "b: " << b.get() << std::endl;
my_template<int> my_int;
my_int.write() = 10;
std::cout << "my_int: " << my_int.get() << std::endl;
my_template<b_class> my_b;
my_b.write().set(2);
std::cout << "my_b: " << my_b.get().get() << std::endl;
// Compile error here:
my_template<a_class> my_a(1);
std::cout << "my_a: " << my_a.get().get() << std::endl;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.