gpt4 book ai didi

c++ - 使用SFINAE,如何避免 'has no member named ...'

转载 作者:行者123 更新时间:2023-11-30 05:27:31 28 4
gpt4 key购买 nike

this question, which asks about SFINAE 开始它给出了以下示例:

template<class T>
std::string optionalToString(T* obj)
{
if (FUNCTION_EXISTS(T->toString))
return obj->toString();
else
return "toString not defined";
}

然而,如果一个对象没有,例如,一个 toString() 函数,而不是在这种情况下返回“toString not defined”,即使我们可以检测到该函数是否存在,编译器仍然会抛出在突出显示指针 toString 调用之前,对象没有名为“toString”的成员的错误。

我希望能够对来自具有不同命名约定的 C++ 库的对象执行相同的操作,例如:

if(R_Contains_SetPosition<TemplateObject>::Value)
{
TemplateObject->SetPosition(X,Y);
}
else if(R_Contains_setPosition<TemplateObject>::Value)
{
TemplateObject->setPosition(X,Y); //TemplateObject doesn't have a setPosition defined!
}

代码已经可以做到,但编译器会在任何调用对象未定义的函数的语句上抛出错误。

有没有办法让编译器接受能够调用成员函数(在这种情况下无论如何都不会运行)的代码(通过重写它或修改编译器标志,最好是前者) ), 即使编译器知道所述成员函数不存在?

澄清:

这不是在询问如何检测函数是否存在。我已经具备这种能力。,它问我如何编写代码来引用对象不一定具有的函数,而编译器不会提示它?

系统是 C++03,因此像解决方案这样的实验性 C++14 在这里无效。

最佳答案

你的问题是无论采用哪个分支都会编译所有分支。所以都必须包含有效代码。

有几种方法可以解决这个问题。标签调度和 SFINAE 是最常见的两种,但它们都不允许您“内联”。

但是,我们可以使用它们通过编写 static_if 来内联完成它助手,并使用 C++14 通用 lambda:

namespace details {
template<class T, class F, class Else>
decltype(auto) static_if( std::true_type, T&&t, F f, Else e ){
return f(std::forward<T>(t));
}
template<class T, class F, class Else>
decltype(auto) static_if( std::false_type, T&&t, F f, Else e ){
return e(std::forward<T>(t));
}
}

template<template<class...>class Test, class T, class F, class Else>
decltype(auto) static_if( T&&t, F f, Else e ){
return details::static_if( Test<T>{}, std::forward<T>(t), std::move(f), std::move(e) );
}

这是一个 static_if 助手。

can_foo<?> .然后你可以像这样使用它:

auto r =
static_if<can_foo>(
t,
[](auto&& t){return t.foo();},
[](auto&&){return 7;}
);

C++14:C++11 解决方案通常无法内联完成,因此您不妨标记分派(dispatch)。

live example .

注意 static_if 的返回类型根据根据第一个参数的类型评估的模板谓词是真还是假而变化。

该参数被传递给真/假分支的 lambda。通常,您会重复使用该名称(隐藏更全局的名称),因为 lambda 中的名称“神奇地”是正确的类型(基本上只有当模板谓词在该类型上返回 true 时才会被评估)。

关于c++ - 使用SFINAE,如何避免 'has no member named ...',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37242375/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com