【问题标题】:Template specialization by argument instead by type通过参数而不是类型的模板专业化
【发布时间】:2019-05-25 00:29:42
【问题描述】:

是否可以通过参数而不是类型来专门化模板类?

目标是拥有一个舒适的界面和尽可能少的执行时间。 目前我知道三种不同的好处。

  1. 根据 CTor 参数具有不同行为的一个类
  2. 定义不同的类
  3. 专门的模板类

第一种可能性不符合执行时间要求。

第二种可能性没有一个很好的界面,因为每个人都必须知道有多个类的行为略有不同。

第三种解决方案是我最喜欢的,但因此需要将类型声明为开关。

所以我正在寻找 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;
}

the above code in coliru

【问题讨论】:

  • 抱歉,C++ 不能这样工作。模板在编译时被实例化。一个专门的模板实例在编译时构建。直到 runtime 才知道调用模板化函数的实际参数。或许可以用constexpr 参数来解决问题,或许,我还没有考虑过。
  • 带有 constexpr 的东西也是我的想法,但不知道怎么做。但肯定是在编译时做切换的目标,这样在运行时就没有开销了。
  • 如果你有一个逻辑上的-constexpr 参数值,该值必须在编译时已知。因此,不要传递它,只需将其用作模板参数即可。如果你不知道它是什么,根据定义,它不能在编译时确定,而是在运行时确定。所以基本上你正在寻找的答案是:使用模板参数。要么你在编译时就知道它,要么你不知道。如果你这样做,那么它可以用作模板参数。结束。
  • 嗯,我不完全理解答案。所以用法与示例中的完全一样——所以它在编译时是众所周知的。但是我不知道如何将它作为模板参数来实现——你介意提供几行代码吗?
  • 模板不限于类型。你也可以写template &lt;bool switch&gt;或类似的。

标签: c++ templates sfinae


【解决方案1】:

谢谢你们——感谢所有可能发现这个问题而不是Using template instead of switch的人

/**
 * opt 4
 */
template<bool _switch>
class inoutT;
template  <>
class inoutT<true>
{
public:
    inoutT(){std::cout << "TTin1" << std::endl;}
    ~inoutT(){std::cout << "TTout1" << std::endl;}
};
template  <>
class inoutT<false>
{
public:
    inoutT(){std::cout << "TTin2" << std::endl;}
    ~inoutT(){std::cout << "TTout2" << std::endl;}
};

working sample of all (listed) possibilities

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多