【问题标题】:Invoking non template function from template function从模板函数调用非模板函数
【发布时间】:2019-04-19 10:54:17
【问题描述】:

我正在尝试从成员模板函数调用成员函数,但它 抱怨没有成员函数的重载。我如何解决它? 下面是测试代码。

class Test
{
public:
    template <typename T>
    void foo(int i, T param)
    {
        switch (i)
        {
        case 1:
            fun(param);
            break;
        case 2:
            bar(param);
        }
    }
    void fun(string p)
    {
        std::cout << "string: " << p << std::endl;
    }
    void bar(double p)
    {
        std::cout << "double: " << p << std::endl;
    }
};

int main() {
    Test t;
    t.foo(1, "hello");
    t.foo(2, 100.0);
    return 0;
}

错误:没有匹配的函数调用 'Test::fun(double&)'

【问题讨论】:

  • 我认为您对模板的作用感到困惑。它们从字面上编译,就好像你要用你写的任何东西替换每个'T'。所以它也尝试调用一个需要双精度的fun。即使在运行时它没有被调用。当您将 2 传递给函数时。该错误应该指向fun(param);。尝试制作一个非模板 foo 并将所有 T 替换为双精度。您希望编译器给出什么错误?

标签: c++ c++11 templates member-functions


【解决方案1】:

看来您要调用funbar 取决于fooparam 参数。如果你使用的是 c++17,你可以使用 if constexpr 来做到这一点:

class Test
{
public:
    template <typename T>
    void foo(T param)
    {
        if constexpr (is_same_v<T,string> || is_same_v<T,const char*>)
            fun(param);
        else if (is_same_v<T,double>)
            bar(param);
    }

    void fun(string p)
    {
        std::cout << "string: " << p << std::endl;
    }

    void bar(double p)
    {
        std::cout << "double: " << p << std::endl;
    }
};

int main() {
    Test t;
    t.foo("hello");
    t.foo(100.0);
    return 0;
}

这里不需要fooint i参数,你根据param类型决定调用哪个fun/bar

【讨论】:

  • 有点超越了重载的目的
【解决方案2】:

对于给定类型typename T,只有当函数体中的每个语句都有效时,才能实例化函数模板。特别是,这包括您的funbar 调用。

要修复它,您需要先修复设计。从您的代码示例中可以看出,我认为您想要类似于:

void foo(double param)
{
    bar(param);
}

void foo(string param)
{
    fun(param);
}

【讨论】:

    猜你喜欢
    • 2018-07-10
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    • 2010-12-20
    • 2013-01-17
    相关资源
    最近更新 更多