简体   繁体   English

带有 const ref 参数的函数模板特化

[英]Function template specialization with const ref arguments

The following code compiles fine .下面的代码编译得很好

#include <iostream>

struct rgb8{
    uint8_t r() const {return 0;};
};


template<typename L, typename P>
L pixelToLevel(P p) {
    return static_cast<L>(p);
}

template<>
uint8_t pixelToLevel<uint8_t, rgb8>(rgb8 p) {  //       <---------- line X
    return pixelToLevel<uint8_t, uint8_t>(p.r());
}


int main()
{
  pixelToLevel<uint8_t>(rgb8());
  return 0;
}

But if in line XI change rgb8 p to const rgb8& p , it fails to compile.但是如果在第 XI 行rgb8 p更改为const rgb8& p ,它将无法编译。

(The exact compiler error generated depends on whether or not the explicit template argument rgb8 is also changed to const rgb8& .) (生成的确切编译器错误取决于显式模板参数rgb8是否也更改为const rgb8& 。)

How can I get it to compile if I want to pass p by reference rather than by value on line X?如果我想通过引用而不是 X 行上的值传递p ,我该如何编译它?

You need to change the template parameter in the declaration of specialization, and template argument when calling it too.您需要更改特化声明中的模板参数,调用它时也需要更改模板参数。 Otherwise the primary template would be called instead.否则将调用主模板。 eg例如

template<>
uint8_t pixelToLevel<uint8_t, const rgb8&>(const rgb8& p) {  //       <---------- line X
    return pixelToLevel<uint8_t, uint8_t>(p.r());
}

then然后

pixelToLevel<uint8_t, const rgb8&>(rgb8());

LIVE居住


EDIT编辑

Given pixelToLevel<uint8_t>(rgb8());鉴于pixelToLevel<uint8_t>(rgb8()); , template argument deduction is performed with primary template and P is deduced as rgb8 (it won't be deduced as const rgb8& with current primary template's parameter declaration), then the specialization version won't be called. , 模板rgb8推导使用主模板进行, P推导为rgb8 (它不会推导出为const rgb8&与当前主模板的参数声明),那么特化版本将不会被调用。

You can apply overloading instead of template specialization.您可以应用重载而不是模板特化。 eg例如

template<typename L, typename P>
L pixelToLevel(P p) {
    return static_cast<L>(p);
}

template<typename L>
L pixelToLevel(const rgb8& p) {  //       <---------- line X
    return pixelToLevel<L, uint8_t>(p.r());
}

Then pixelToLevel<uint8_t>(rgb8());然后pixelToLevel<uint8_t>(rgb8()); would select the 2nd overload.将选择第二个过载。

LIVE居住

An alternate solution to @songyuanyao's would be @songyuanyao 的另一种解决方案是

template<typename L, typename P>
L pixelToLevel(const P& p) {
    return static_cast<L>(p);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM