模板函数将另一个模板函数的第一个参数作为同一类内部模板函数的参数。

huangapple go评论110阅读模式
英文:

Template function taking as argument 1 of the other template functions inside same class

问题

我要翻译的部分如下:

"The objective I'm aiming to is creating a function, among all the "operative" functions, that takes as 3rd argument, one of the other functions inside the class. Say we have 4 template functions that respectively sum(doAdd), subtract(doSub), multiply(doMul) and divide(doDiv) 2 numbers, whichever their type may be."

// FunctionPointers.hh
namespace FunctionPointers {
    class FunctionPointer {
        public:
            //// Operative functions ////
            template<typename T, typename U>
            T doAdd(T& a, U& b) { T res; return res = a + b; }

            template<typename T, typename U>
            T doSub(T& a, U& b) { T res; return res = a - b; }

            template<typename T, typename U>
            T doMUl(T& a, U& b) { T res; return res = a * b; }

            template<typename T, typename U>
            T doDiv(T& a, U& b) { 
                T res;
                if (b == 0) return false;
                return res = a / b; 
            }
    };
}

A use case would be:

// FunctionPointers.cpp
#inlcude <iostream>
using std::cout;
using std::endl;

FunctionPointers::FunctionPointer* FP = new FunctionPointers::FunctionPointer();

int main() {
    int a = 1; float b = 3.1415;

    cout << FP->doAdd(a, b) << endl;
    cout << FP->doSub(a, b) << endl;

    // Something the likes of this
    cout << FP->doOp(a, b, doAdd) << endl;

    return 1;
}

What is the best approach to such problem? Does a solution even exist that is compatible with the written header and main file?

英文:

The objective I'm aiming to is creating a function, among all the "operative" functions, that takes as 3rd argument, one of the other functions inside the class. Say we have 4 template functions that respectively sum(doAdd), subtract(doSub), multiply(doMul) and divide(doDiv) 2 numbers, whichever their type may be.

// FunctionPointers.hh
namespace FunctionPointers {
    class FunctionPointer {
        public:
            //// Operative functions ////
            template<typename T, typename U>
            T doAdd(T& a, U& b) { T res; return res = a + b; }

            template<typename T, typename U>
            T doSub(T& a, U& b) { T res; return res = a - b; }

            template<typename T, typename U>
            T doMUl(T& a, U& b) { T res; return res = a * b; }

            template<typename T, typename U>
            T doDiv(T& a, U& b) { 
                T res;
                if (b == 0) return false;
                return res = a / b; 
            }
    };
}

A use case would be:

// FunctionPointers.cpp
#inlcude <iostream>
using std::cout;
using std::endl;

FunctionPointers::FunctionPointer* FP = new FunctionPointers::FunctionPointer();

int main() {
    int a = 1; float b = 3.1415;

    cout << FP->doAdd(a, b) << endl;
    cout << FP->doSub(a, b) << endl;

    // Something the likes of this
    cout << FP->doOp(a, b, doAdd) << endl;

    return 1;
}

What is the best approach to such problem? Does a solution even exist that is compatible with the written header and main file?

答案1

得分: 1

template<typename T, typename U, typename F>
T doOp(T& a, U& b, F f)
{
    return std::invoke(f, this, a, b);
}

int main() {
    FunctionPointers::FunctionPointer FP;
    int a = 1; float b = 3.1415;

    std::cout << FP.doAdd(a, b) << std::endl;
    std::cout << FP.doSub(a, b) << std::endl;

    // Something the likes of this
    std::cout << FP.doOp(a, b, &FunctionPointers::FunctionPointer::doAdd<int, float>) << std::endl;
}

演示


<details>
<summary>英文:</summary>

You might do

template<typename T, typename U, typename F>
T doOp(T& a, U& b, F f)
{
return std::invoke(f, this, a, b);
}


And then

int main() {
FunctionPointers::FunctionPointer FP;
int a = 1; float b = 3.1415;

std::cout &lt;&lt; FP.doAdd(a, b) &lt;&lt; std::endl;
std::cout &lt;&lt; FP.doSub(a, b) &lt;&lt; std::endl;

// Something the likes of this
std::cout &lt;&lt; FP.doOp(a, b, &amp;FunctionPointers::FunctionPointer::doAdd&lt;int, float&gt;) &lt;&lt; std::endl;
[Demo](https://godbolt.org/z/3Kf8G6oTo)

</details>



# 答案2
**得分**: 1

你可以做的另一件事情是将地址发送给你想要调用的成员函数模板,但那么你可能就直接调用它了。

另一件事情是可以设置一些标志,例如:

```cpp
enum class op {
    add, sub, mul, div
};

然后有一个处理这些标志的函数:

template <auto O, class A, class B>
auto doOp(A a, B b)
{
    switch (O) {
        case op::add: return doAdd(a, b);
        case op::sub: return doSub(a, b);
        case op::mul: return doMul(a, b);
        case op::div: return doDiv(a, b);
    }
}

然后像这样使用它:

FunctionPointers::FunctionPointer FP;
std::cout << FP.doOp<op::add>(a, b);

但你也可以这样做:

namespace FunctionPointers {
class FunctionPointer {
public:
    // ...
    template <class T, class A, class B>
    auto Do(A a, B b)
    {
        return T{}.operator()(a, b);
    }
};
} // namespace FunctionPointers

int main()
{
    int a = 1;
    float b = 3.1415;

    FunctionPointers::FunctionPointer FP;
    cout << FP.Do<std::divides<>>(a, b);
}
英文:

One thing you could do is sending the address to the member function template you want to call, but then you might as well just call it directly.

Another thing you could do is having some flags, ex:

enum class op {
    add, sub, mul, div
};

and then a function to handle the flags

template &lt;auto O, class A, class B&gt;
auto doOp(A a, B b)
{
    switch (O) {
        case op::add: return doAdd(a, b);
        case op::sub: return doSub(a, b);
        case op::mul: return doMUl(a, b);
        case op::div: return doDiv(a, b);
    }
}

and use it like so

FunctionPointers::FunctionPointer FP;
std::cout &lt;&lt; FP.doOp&lt;op::add&gt;(a, b);

But then you might as well just do

namespace FunctionPointers {
class FunctionPointer {
public:
    // ...
    template &lt;class T, class A, class B&gt;
    auto Do(A a, B b)
    {
        return T{}.operator()(a, b);
    }
};
} // namespace FunctionPointers

int main()
{
    int a = 1;
    float b = 3.1415;

    FunctionPointers::FunctionPointer FP;
    cout &lt;&lt; FP.Do&lt;std::divides&lt;&gt;&gt;(a, b);
}

huangapple
  • 本文由 发表于 2023年6月22日 03:22:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76526509.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定