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

问题描述

由于种种与本文无关的原因,我试图将我的类转换为函数指针。

当我尝试使用非模板类执行此操作时,它可以正常工作。下面,Bar bar; bar(1)正确地编译,并且段错误按预期进行。但是Foo<int>; foo(1)根本不编译。

我尝试了多个编译器,但得到:mismatched types 'Args' and 'int'

有什么想法吗?现场演示: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;
}

也尝试过这种糟糕的语法:

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

解决方法

您可以尝试以下方法:

#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;
}

使用Visual C ++ 2019时,我得到以下运行时输出:

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

使用static_cast是为了强制使用重载的运算符成员函数。

,

或者,您也可以尝试:

#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;
}

使用Visual C ++ 2019时,我得到以下运行时输出:

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

通过这种方式,该对象现在可以被调用并返回一个函数指针。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...