如何消除成员函数与成员函数模板的歧义

问题描述 投票:0回答:1

我需要将成员函数的指针作为参数传递给其他函数。我使用

std::mem_fn
将它们包装在函数对象中。

有时成员函数会重载。我学习了两种语法形式来消除重载的歧义:

  • 为了消除模板成员函数的歧义,我在指向成员的指针表达式中使用
    T::template member<template-args>
  • 为了在所有重载都是非模板成员函数时消除非模板成员函数的歧义,我将函数类型作为显式模板参数传递给
    mem_fn
    mem_fn<return-type(args-types)>(pointer-to-member-expression)

但是,当某些重载是模板成员函数时,应该使用什么语法来消除非模板成员函数的歧义呢?我的直接猜测无法编译:

#include <iostream>   // cout
#include <functional> // mem_fn

struct C {
    void f() { std::cout << "f()\n"; }
    void f(int) { std::cout << "f(int)\n"; }

    template <class T>
    void g(T) { std::cout << "g(T)\n"; }
    template <class T1, class T2>
    void g(T1) { std::cout << "g<T1,T2>(T1)\n"; }

    template <class T>
    void h(T) { std::cout << "h(T)\n"; }
    void h(int) { std::cout << "h(int)\n"; }
};

int main() {
    C c;
    // non-template member function vs non-template member function
    std::mem_fn<void()>(&C::f)(c);
    std::mem_fn<void(int)>(&C::f)(c, 1);

    // template member function vs template member function
    std::mem_fn(&C::template g<int>)(c, 1);
    std::mem_fn(&C::template g<int, int>)(c, 1);

    // non-template member function vs template member function
    std::mem_fn(&C::template h<int>)(c, 1);
    // gcc: error: no matching function for call to 'mem_fn<void(int)>(<unresolved overloaded function type>)'
    // clang: error: no matching function for call to 'mem_fn'
    // std::mem_fn<void(int)>(&C::h)(c, 1);

    return 0;
}

另请参阅:https://godbolt.org/z/39dd569cK

FWIW 我使用 C++20,但在 C++11 中也看到相同的错误。

c++ templates overloading function-pointers disambiguation
1个回答
0
投票

您可以提供所有模板参数:

std::mem_fn<void(int), C>(&C::h)(c, 1);

演示

© www.soinside.com 2019 - 2024. All rights reserved.