推导模板类重载方法的地址会导致"error: expected primary-expression before ‘decltype’"

Deducing address of template class's overloaded method results in "error: expected primary-expression before ‘decltype’"

本文关键字:expected error primary-expression decltype before 重载 方法 地址      更新时间:2023-10-16

我正在尝试找到一个类型&然后分配方法,例如:

decltype(std::addressof(&std::vector<int>::push_back<int&&>)) x =
&std::vector<int>::push_back;

我被困在以下错误:

错误:在"decltype"之前需要主表达式

以上代码只是一个极小的例子。实际上,方法的地址将与其类型一起传递给模板类。即它也可以是CCD_ 2。因此,auto可能不是一个选项
查看伪代码:

template<typename Type, // <-- int, float
template<typename...> class Container, // <-- std::vector, std::set
typename Method_t,  // <-- decltype(push_back(T&&), insert(T&&))
Method_t Method>  // <-- push_back(T&&), insert(T&&)
struct Wrap { ... };
#define WRAP(TYPE, CONTAINER, METHOD) 
Wrap<TYPE, CONTAINER, decltype(&CONTAINER<TYPE>::METHOD<TYPE&&>), &CONTAINER<TYPE>::METHOD>

用法

WRAP(int, std::vector, push_back); // uses `push_back(int&&)`
WRAP(float, std::set, insert);  // uses `insert(float&&)`

推断模板类重载成员方法地址的正确方法是什么

在我的情况下,Method_t应该是仅具有T&&过载版本的push_backinsertpush_frontpush中的任何一个
这个Qn没有帮助:模板化成员函数的地址

首先,std::addressof获取对象的地址,而不是成员的地址(在指向成员的指针的意义上)

其次,std::vector<int>::push_back不是一个模板。

第三,为了在获取函数地址时控制过载分辨率,请使用强制转换表示法:

static_cast<void (std::vector<int>::*)(int&&)>(&std::vector<int>::push_back)
//          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
//          overload                            name of overload set

到目前为止,还不可能自动推导重载函数本身。需要在左侧指定其完整签名,编译器才能推导出合适的类型
示例:用于以下2个功能:

void C::foo (int);
void C::foo (double);

必须提到LHS上的完整原型,

void (C::*method)(int) = &C::foo;  // OK

但不幸的是,我们不能做像这样的事情

auto method = &C::foo(int);  // not allowed

因此,无论Qn中要求什么,都不可能以目前的形式实现


但如果对需求进行了少量调整,则可以推断出返回类型,并且仍然可以获得最终所需的结果
以下是struct Wrap:的语法更改

template<typename Type,
template<typename...> class Container,
typename Return,  // <--- changed
Return (Container<Type>::*Method)(Type&&)>  // <--- full definition
struct Wrap { ... }

有了上面更改的代码,我们只需要推导"返回类型",而不是推导整个方法的类型。已知参数是Type&&,正如在Qn中已经指定的那样。现在WRAP宏看起来是这样的:

#define WRAP(TYPE, CONTAINER, METHOD) 
Wrap<TYPE, CONTAINER, decltype(((CONTAINER<TYPE>*)nullptr)->METHOD(TYPE())), &CONTAINER<TYPE>::METHOD>

用法

WRAP(int, std::vector, push_back) wrap;

应用程序演示。

相关文章: