我的代码需要测试各种像素类型的“有效性”。例如,如果浮点像素报告(async () => {
// install proxy-chain "npm i proxy-chain --save"
const proxyChain = require('proxy-chain');
// change username & password
const oldProxyUrl = 'http://lum-customer-USERNAMEOFLUMINATI-zone-static-country-us:PASSWORDOFLUMINATI@zproxy.lum-superproxy.io:22225';
const newProxyUrl = await proxyChain.anonymizeProxy(oldProxyUrl);
const browser = await puppeteer.launch({
headless: false,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
`--proxy-server=${newProxyUrl}`
]
});
const page = await browser.newPage();
await page.goto('https://www.whatismyip.com/');
await page.screenshot({ path: 'example.png' });
await browser.close();
})();
的{{1}},则无效。
因此,我有一个“验证器”模板结构,我专门针对各种像素类型(此处仅针对true
)。我的代码使用全局模板函数通过SFINAE调用正确的重载
std::isnan()
这个例子很好用。选择float
的{{1}}专业化。一切都很好。
但是后来我尝试通过专门针对// Dummy implementation breaks compilation if no overload found.
template<class PEL, typename Enable=void> struct pixel_validator { };
template<class PEL>
struct pixel_validator<PEL, typename std::enable_if<std::is_floating_point<PEL>::value>::type>
{
static bool validate(const PEL& p) { return !std::isnan(p); }
};
template<class PEL>
inline bool is_valid_pixel(const PEL& p)
{
// Dispatch to validator above
return pixel_validator<PEL>::validate(p);
};
void main
{
float x = 1.0f;
std::cout << "is it valid ?" << std::boolalpha << is_valid_pixel(x);
}
的自定义版本“ pixel_validator
”来减少模板表达式的冗长性。
float
所以现在不用写这个:
std::enable_if
我会写
float
...因此我的验证者变为:
template<class T, class VAL=T>
struct enable_if_floating
: std::enable_if<std::is_floating_point<T>::value, VAL>
{};
不幸的是,当我更改“ std::enable_if<std::is_floating_point<PEL>::value>::type
”以使用它时,代码无法构建。我的enable_if_floating<PEL>::value
无法正常工作,因此Visual Studio无法找到合适的专业化名称。那我的输出就不足为奇了。
template<class PEL>
struct pixel_validator<PEL, typename enable_if_floating<PEL>::type>
{
static bool validate(const PEL& p) { return !std::isnan(p); }
};
我的问题是,为什么?我的pixel_validator
有什么问题?
注意:我甚至将此代码放在我的enable_if_floating
中,只是为了进行完整性检查。如果我的模板不好,我会期望1>------ Build started: Project: TestApp7, Configuration: Debug Win32 ------
1>TestApp7.cpp
1>C:\Test\TestApp7\TestApp7.cpp(62,34): error C2039: 'validate': is not a member of 'pixel_validator<PEL,void>'
1>C:\Test\TestApp7\TestApp7.cpp(62,34): error C2039: with
1>C:\Test\TestApp7\TestApp7.cpp(62,34): error C2039: [
1>C:\Test\TestApp7\TestApp7.cpp(62,34): error C2039: PEL=float
1>C:\Test\TestApp7\TestApp7.cpp(62,34): error C2039: ]
1>C:\Test\TestApp7\TestApp7.cpp(62): message : see declaration of 'pixel_validator<PEL,void>'
1>C:\Test\TestApp7\TestApp7.cpp(62): message : with
1>C:\Test\TestApp7\TestApp7.cpp(62): message : [
1>C:\Test\TestApp7\TestApp7.cpp(62): message : PEL=float
1>C:\Test\TestApp7\TestApp7.cpp(62): message : ]
1>C:\Test\TestApp7\TestApp7.cpp(82): message : see reference to function template instantiation 'bool is_valid_pixel<float>(const PEL &)' being compiled
1>C:\Test\TestApp7\TestApp7.cpp(82): message : with
1>C:\Test\TestApp7\TestApp7.cpp(82): message : [
1>C:\Test\TestApp7\TestApp7.cpp(82): message : PEL=float
1>C:\Test\TestApp7\TestApp7.cpp(82): message : ]
1>C:\Test\TestApp7\TestApp7.cpp(62,1): error C3861: 'validate': identifier not found
1>Done building project "TestApp7.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
失败,但是不会失败。
enable_if_floating
还请注意:我的现实世界代码使用的谓词比这个简单的示例节省了更多的空间
答案 0 :(得分:2)
不确定是唯一的问题,但是是一个问题。
如果你写
template<class T, class VAL=T>
struct enable_if_floating
: std::enable_if<std::is_floating_point<T>::value, VAL>
{};
默认返回的type
是T
,其中std::is_enable_if
是void
。
所以
template<class PEL>
struct pixel_validator<PEL, typename enable_if_floating<PEL>::type>
{
static bool validate(const PEL& p) { return !std::isnan(p); }
};
当PEL
是浮点类型时,
template<class PEL> // .....VVV should be void, not PEL
struct pixel_validator<PEL, PEL>
{
static bool validate(const PEL& p) { return !std::isnan(p); }
};
与pixel_validator
声明(和主定义)不匹配的
template<class PEL, typename Enable=void>
struct pixel_validator
{ };
因为预期的第二种类型是void
,而不是PEL
。
我看到两种可能的替代解决方案:或者您将void
作为第二个模板模板参数enable_is_floating
的默认值
// ...........................VVVV
template<class T, class VAL = void>
struct enable_if_floating
: std::enable_if<std::is_floating_point<T>::value, VAL>
{ };
或者您将PEL
作为pixel_validator
第二个模板参数的默认值
template <typename PEL, typename = PEL>
struct pixel_validator
{ };
我建议第一个与std::enable_if
和标准C ++库同质的人。