简体   繁体   English

模板类中的模板转换运算符 - 到函数指针

[英]Template conversion operator in template class - to function pointer

I'm trying to make my class be convertible to a function pointer, for a slew of reasons unrelated to this post.我试图让我的类可以转换为函数指针,原因与这篇文章无关。

When I try to do this with a non-template class, it works fine.当我尝试使用非模板类执行此操作时,它工作正常。 Below, Bar bar; bar(1)下面, Bar bar; bar(1) Bar bar; bar(1) correctly compiles, and segfaults as-expected. Bar bar; bar(1)正确编译,并按预期出现段错误。 But Foo<int>; foo(1)但是Foo<int>; foo(1) Foo<int>; foo(1) doesn't compile at all. Foo<int>; foo(1)根本无法编译。

I've tried multiple compilers, and I get: mismatched types 'Args' and 'int'我尝试了多个编译器,但我得到了: mismatched types 'Args' and 'int'

Any ideas?有任何想法吗? Live demo: https://wandbox.org/permlink/alSGBssfSd4pHgdl现场演示: https : //wandbox.org/permlink/alSGBssfSd4pHgdl

#include <iostream>
#include <tuple>

using namespace std;

template<typename... Args>
using Test = void(*)(Args...);

template<typename T>
struct Foo {
    template<typename... Args>
    operator Test<Args...>() {
        return Test<Args...>{};
    }
};

struct Bar {
    template<typename... Args>
    operator Test<Args...>() {
        return Test<Args...>{};
    }
};

int main()
{
    Foo<int> foo;
    // foo(1);
    
    Bar bar;
    bar(1);
    
    return 0;
}

Tried this awful syntax, too:也尝试过这种糟糕的语法:

    template<typename... Args>
    (*operator void() const)(Args...) {
      return {};
    }

You can try this:你可以试试这个:

#include <iostream>
#include <tuple>

using namespace std;

template<typename... Args>
using Test = void(*)(Args...);

template<typename T>
struct Foo {
    template<typename... Args>
    operator Test<Args...>()
    {
        std::cout << __FUNCTION__ << std::endl;
        return Test<Args...>{};
    }
};

struct Bar {
    template<typename... Args>
    operator Test<Args...>()
    {
        std::cout << __FUNCTION__ << std::endl;
        return Test<Args...>{};
    }
};

int main()
{
    Foo<int> foo;
    auto x = static_cast<Test<int, double>>(foo);

    Bar bar;
    auto y = static_cast<Test<char, float>>(bar);

    return 0;
}

When using Visual C++ 2019, I get the following run-time output:使用 Visual C++ 2019 时,我得到以下运行时输出:

Foo<int>::operator void (__cdecl *)(int,double)
Bar::operator void (__cdecl *)(char,float)

The use of the static_cast is to force the usage of the overloaded operator member functions. static_cast的用途是强制使用重载的运算符成员函数。

Alternatively, you can also try:或者,您也可以尝试:

#include <iostream>
#include <tuple>
#include <type_traits>

using namespace std;

template<typename... Args>
using Test = void(*)(Args...);

template<typename T>
struct Foo {
    template<typename... Args>
    Test<Args...> operator()(int x)
    {
        return Test<Args...>{};
    }
};

struct Bar {
    template<typename... Args>
    Test<Args...> operator()(int x)
    {
        return Test<Args...>{};
    }
};

int main()
{
    Foo<int> foo;

    auto w = foo.template operator()<int, double>(1);
    std::cout << "w: " << typeid(w).name() << std::endl;

    auto x = foo(2);
    std::cout << "x: " << typeid(x).name() << std::endl;


    Bar bar;

    auto y = bar.template operator()<char, float>(3);
    std::cout << "y: " << typeid(y).name() << std::endl;

    auto z = bar(4);
    std::cout << "z: " << typeid(z).name() << std::endl;

    return 0;
}

When using Visual C++ 2019, I get the following run-time output:使用 Visual C++ 2019 时,我得到以下运行时输出:

w: void (__cdecl*)(int,double)
x: void (__cdecl*)(void)
y: void (__cdecl*)(char,float)
z: void (__cdecl*)(void)

In this way, the object is now callable and returns a function pointer.这样,对象现在是可调用的并返回一个函数指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM