首页 > 解决方案 > C++ 模棱两可的模板重载

问题描述

我正在尝试使用模板专业化来根据模板变量的值返回不同的类型。

我已经从尝试在运行时分支而不是在编译时使用非专业typeof()模板和使用std::enable_if_t<>. 我认为这可能源于对模板函数如何解析缺乏了解。

class Test
{
public:
    template <typename T>
    T request()
    {
        T ret = getVal<T>();
        return ret;
    }

private:
    float foo = 2.f;
    int bar = 1;

    template <typename T>
    typename std::enable_if<std::is_same<T, float>::value, bool>::type
    getVal() { return foo; }

    template <typename T>
    typename std::enable_if<std::is_same<T, int>::value, bool>::type
    getVal() { return bar; }

    template<typename T>
    T getVal()
    {
        std::cout << "T is type " << typeid(T).name() << std::endl;
        throw std::bad_typeid();
    }
};

int main()
{
    Test t;
    int i;
    float f;
    i = t.template request<int>();
    f = t.template request<float>();
}

我希望这可以解决三个不同的功能,但我不确定它是否是:

T Test::getVal()

int Test::getVal()

float Test::getVal()

任何帮助将不胜感激。

标签: c++templatestemplate-specialization

解决方案


您的问题是,template<typename T> T getVal()当 SFINAEd 成功时,使呼叫模棱两可。

一种解决方案是用补码条件限制那个...

但是标签调度是解决问题的一种简单的替代方法:

template <typename> struct Tag{};

class Test
{
public:
    template <typename T>
    T request() const
    {
        return getVal(Tag<T>{});
    }

private:
    float foo = 2.f;
    int bar = 1;

    float getVal(Tag<float>) const { return foo; }
    int getVal(Tag<int>) const { return bar; }

    template<typename T> void getVal(Tag<T>) = delete;
};

推荐阅读