【发布时间】:2019-05-25 00:29:42
【问题描述】:
是否可以通过参数而不是类型来专门化模板类?
目标是拥有一个舒适的界面和尽可能少的执行时间。 目前我知道三种不同的好处。
- 根据 CTor 参数具有不同行为的一个类
- 定义不同的类
- 专门的模板类
第一种可能性不符合执行时间要求。
第二种可能性没有一个很好的界面,因为每个人都必须知道有多个类的行为略有不同。
第三种解决方案是我最喜欢的,但因此需要将类型声明为开关。
所以我正在寻找 1. 和 3. 之间的混合物。
我可能缺少正确的搜索关键字。
目前我知道的可能性如下:
#include <iostream>
/**
* opt1 -- switch at runtime
*/
class inoutslow
{
public:
inoutslow(bool b): _switch(b)
{
if(_switch)
std::cout << "slowIn1" << std::endl;
else
std::cout << "slowIn2" << std::endl;
}
~inoutslow()
{
if(_switch)
std::cout << "slowOut1" << std::endl;
else
std::cout << "slowOut2" << std::endl;
}
private:
bool _switch;
};
/**
* opt2 -- different self defined classes
*/
class inout1
{
public:
inout1(){std::cout << "in1" << std::endl;}
~inout1(){std::cout << "out1" << std::endl;}
};
class inout2
{
public:
inout2(){std::cout << "in2" << std::endl;}
~inout2(){std::cout << "out2" << std::endl;}
};
/**
* opt3 -- specialized template
*/
struct trueType;
struct falseType;
template<typename T>
class inout
{
public:
inout(){std::cout << "DefaultTin" << std::endl;}
~inout(){std::cout << "DefaultTout" << std::endl;}
};
template <>
class inout<trueType>
{
public:
inout(){std::cout << "Tin1" << std::endl;}
~inout(){std::cout << "Tout1" << std::endl;}
};
template <>
class inout<falseType>
{
public:
inout(){std::cout << "Tin2" << std::endl;}
~inout(){std::cout << "Tout2" << std::endl;}
};
int main()
{
inoutslow i(true);
inoutslow j(false);
inout1 ii;
inout2 jj;
inout<trueType> iii;
inout<falseType> jjj;
}
【问题讨论】:
-
抱歉,C++ 不能这样工作。模板在编译时被实例化。一个专门的模板实例在编译时构建。直到 runtime 才知道调用模板化函数的实际参数。或许可以用
constexpr参数来解决问题,或许,我还没有考虑过。 -
带有 constexpr 的东西也是我的想法,但不知道怎么做。但肯定是在编译时做切换的目标,这样在运行时就没有开销了。
-
如果你有一个逻辑上的-
constexpr参数值,该值必须在编译时已知。因此,不要传递它,只需将其用作模板参数即可。如果你不知道它是什么,根据定义,它不能在编译时确定,而是在运行时确定。所以基本上你正在寻找的答案是:使用模板参数。要么你在编译时就知道它,要么你不知道。如果你这样做,那么它可以用作模板参数。结束。 -
嗯,我不完全理解答案。所以用法与示例中的完全一样——所以它在编译时是众所周知的。但是我不知道如何将它作为模板参数来实现——你介意提供几行代码吗?
-
模板不限于类型。你也可以写
template <bool switch>或类似的。