在 main 中使用模板在 C++ 中创建默认构造函数
Using template to create default constructor in C++ in main
有没有办法使用模板在您的 main 中创建 class 的标准构造函数?
如果我有 class:
myclass.h
class myClass
{
private:
float a;
public:
myClass(float _a) {a = _a;}
float getA(){return a;}
~myClass() {}
};
有没有办法像这样在您的 main 中进行模板化:
main.cpp
#include "myclass.h"
typedef myClass<5.0> Dummy
int main(int argc, char const *argv[])
{
// EDIT: removed the following typo
// Dummy dummy();
Dummy dummy;
std::cout << dummy.getA() << std::endl;
return 0;
}
应该输出:
> 5.0000000
这样人们就可以大体上定义一种构造实例的标准方法。
C++17 及以下
不幸的是,C++ 还不允许您使用浮点类型作为非类型模板参数。也就是说,您可以通过接受分子和分母作为整数来伪造它,然后在 class 中进行“数学运算”以获得浮点值。看起来像
template<size_t numerator, size_t denominator = 1> // use a default value so you don't have to specify the denominator for whole values
class myClass
{
private:
float a;
public:
myClass(float _a = static_cast<float>(numerator) / denominator) : a(_a) {}
float getA(){return a;}
~myClass() {}
};
typedef myClass<5> Dummy;
int main(int argc, char const *argv[])
{
Dummy dummy; // notice this isn't Dummy dummy();. That makes a function, not a variable
std::cout << dummy.getA() << std::endl;
return 0;
}
如果需要,您还可以将默认值添加到 numerator
,这样您就可以
// Pre C++17
myClass<> foo;
//C++17 and later
myClass foo;
C++20
现在我们可以使用浮点类型了1代码可以简化为:
template<float default_value = 0.0f>
class myClass
{
private:
float a;
public:
myClass(float _a = default_value) : a(_a) {}
float getA(){return a;}
~myClass() {}
};
typedef myClass<5.0f> Dummy;
int main(int argc, char const *argv[])
{
Dummy dummy;
std::cout << dummy.getA() << std::endl;
return 0;
}
1: 目前还没有编译器真正支持这个,但根据标准
不是真的,但是你可以像这样写一个工厂函数(或者 class 如果它更复杂的话):
myClass createMyClassV5()
{
return myClass(5.0);
}
很遗憾,您不能将其设为模板,因为 float
不允许作为模板非类型参数。不过,您可以使用 int
来完成。
您最好只使用默认实例,您可以在需要新实例时复制该实例:
#include "myclass.h"
Dummy myClass(5.0);
int main(int argc, char const *argv[])
{
myClass dummy1 = Dummy;
std::cout << dummy1.getA() << std::endl;
myClass dummy2 = Dummy;
std::cout << dummy2.getA() << std::endl;
return 0;
}
在 的基础上,您可以创建 "factory factory function":
auto makeMyClassFactory(float value) {
return [=] {
return myClass{value};
};
}
auto const Dummy = makeMyClassFactory(5.0f);
int main(int argc, char const *argv[])
{
auto dummy = Dummy();
std::cout << dummy.getA() << std::endl;
return 0;
}
有没有办法使用模板在您的 main 中创建 class 的标准构造函数?
如果我有 class:
myclass.h
class myClass
{
private:
float a;
public:
myClass(float _a) {a = _a;}
float getA(){return a;}
~myClass() {}
};
有没有办法像这样在您的 main 中进行模板化:
main.cpp
#include "myclass.h"
typedef myClass<5.0> Dummy
int main(int argc, char const *argv[])
{
// EDIT: removed the following typo
// Dummy dummy();
Dummy dummy;
std::cout << dummy.getA() << std::endl;
return 0;
}
应该输出:
> 5.0000000
这样人们就可以大体上定义一种构造实例的标准方法。
C++17 及以下
不幸的是,C++ 还不允许您使用浮点类型作为非类型模板参数。也就是说,您可以通过接受分子和分母作为整数来伪造它,然后在 class 中进行“数学运算”以获得浮点值。看起来像
template<size_t numerator, size_t denominator = 1> // use a default value so you don't have to specify the denominator for whole values
class myClass
{
private:
float a;
public:
myClass(float _a = static_cast<float>(numerator) / denominator) : a(_a) {}
float getA(){return a;}
~myClass() {}
};
typedef myClass<5> Dummy;
int main(int argc, char const *argv[])
{
Dummy dummy; // notice this isn't Dummy dummy();. That makes a function, not a variable
std::cout << dummy.getA() << std::endl;
return 0;
}
如果需要,您还可以将默认值添加到 numerator
,这样您就可以
// Pre C++17
myClass<> foo;
//C++17 and later
myClass foo;
C++20
现在我们可以使用浮点类型了1代码可以简化为:
template<float default_value = 0.0f>
class myClass
{
private:
float a;
public:
myClass(float _a = default_value) : a(_a) {}
float getA(){return a;}
~myClass() {}
};
typedef myClass<5.0f> Dummy;
int main(int argc, char const *argv[])
{
Dummy dummy;
std::cout << dummy.getA() << std::endl;
return 0;
}
1: 目前还没有编译器真正支持这个,但根据标准
不是真的,但是你可以像这样写一个工厂函数(或者 class 如果它更复杂的话):
myClass createMyClassV5()
{
return myClass(5.0);
}
很遗憾,您不能将其设为模板,因为 float
不允许作为模板非类型参数。不过,您可以使用 int
来完成。
您最好只使用默认实例,您可以在需要新实例时复制该实例:
#include "myclass.h"
Dummy myClass(5.0);
int main(int argc, char const *argv[])
{
myClass dummy1 = Dummy;
std::cout << dummy1.getA() << std::endl;
myClass dummy2 = Dummy;
std::cout << dummy2.getA() << std::endl;
return 0;
}
在
auto makeMyClassFactory(float value) {
return [=] {
return myClass{value};
};
}
auto const Dummy = makeMyClassFactory(5.0f);
int main(int argc, char const *argv[])
{
auto dummy = Dummy();
std::cout << dummy.getA() << std::endl;
return 0;
}