Deducing address of template class's overloaded method results in "error: expected primary-expression before ‘decltype’"
Deducing address of template class's overloaded method results in "error: expected primary-expression before ‘decltype’"
我正在尝试寻找类型然后分配方法,例如:
decltype(std::addressof(&std::vector<int>::push_back<int&&>)) x =
&std::vector<int>::push_back;
我遇到了以下错误:
error: expected primary-expression before ‘decltype
’
以上代码只是一个最小的例子。实际上,方法的地址将连同其类型一起传递给模板 class。即它也可以是 &std::set<T>::insert<T&&>
。因此 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&&)`
推导模板class重载成员方法地址的正确方法是什么?
在我的例子中,Method_t
应该是 push_back
、insert
、push_front
、push
和 T&&
仅重载版本。
这个 Qn 没有帮助:Address of templated member function
首先,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 中要求什么,都不可能以其当前形式实现。
但如果要求稍作调整,则可以推导出 return 类型并仍然达到最终预期的结果。
struct Wrap
:
的语法略有改动
template<typename Type,
template<typename...> class Container,
typename Return, // <--- changed
Return (Container<Type>::*Method)(Type&&)> // <--- full definition
struct Wrap { ... }
使用上面更改的代码,我们不需要推导整个方法的类型,我们只需要推导"return type"。正如已在 Qn 中指定的那样,该参数已知为 Type&&
。现在 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;
申请Demo.
我正在尝试寻找类型然后分配方法,例如:
decltype(std::addressof(&std::vector<int>::push_back<int&&>)) x =
&std::vector<int>::push_back;
我遇到了以下错误:
error: expected primary-expression before ‘
decltype
’
以上代码只是一个最小的例子。实际上,方法的地址将连同其类型一起传递给模板 class。即它也可以是 &std::set<T>::insert<T&&>
。因此 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&&)`
推导模板class重载成员方法地址的正确方法是什么?
在我的例子中,Method_t
应该是 push_back
、insert
、push_front
、push
和 T&&
仅重载版本。
这个 Qn 没有帮助:Address of templated member function
首先,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 中要求什么,都不可能以其当前形式实现。
但如果要求稍作调整,则可以推导出 return 类型并仍然达到最终预期的结果。
struct Wrap
:
template<typename Type,
template<typename...> class Container,
typename Return, // <--- changed
Return (Container<Type>::*Method)(Type&&)> // <--- full definition
struct Wrap { ... }
使用上面更改的代码,我们不需要推导整个方法的类型,我们只需要推导"return type"。正如已在 Qn 中指定的那样,该参数已知为 Type&&
。现在 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;
申请Demo.