无法自动确定模板类型的隐式转换运算符

时间:2019-08-08 14:28:05

标签: c++ templates c++17

我有一个带有隐式转换运算符的模板化类thing,如下所示:

#include <stdio.h>

template <typename T>
struct thing
{
    T t;

    operator const T&() const 
    { 
        return t;
    }
};

template <typename T>
struct B 
{
    T t;
};

void fun(const int&) {
    printf("int\n");
}

template <typename T>
void fun(const B<T>&) {
    printf("B<T>\n");
}

int main()
{
    thing<int> a;
    fun(a);

    thing<B<int>> b;
    fun(b);

    return 0;
}

使用fun(const int&)调用thing<int>,编译器可以找出调用隐式转换运算符的方式,以传递const T&(在本例中为const int&)到fun(const int&)

但是,对于thing<B<int>>,编译器无法确定我希望调用fun(const B<T>&)

我如何帮助编译器明确地将b强制转换为const B<int>&(例如,使用static_cast<const B<int>&>(b))?

我的具体使用场景类似于约束条件所提供的代码,该约束条件是我将B用于大约10种不同类型的T,即,不是任意许多不同的T。如果我必须创建〜10个模板专业化,那就这样吧。但是,在这种情况下,我不完全知道如何最好地重载struct B。但是也许我走错了路-也许存在更简单/更优雅的解决方案吗?

2 个答案:

答案 0 :(得分:3)

  

如何在不将b强制转换为const B<int>&的情况下帮助编译器解决此问题?

不能。模板不执行任何隐式转换。他们推断出参数的类型,也就是他们使用的类型。

您可以做的一件事就是在包装器中添加一个get函数,例如

template <typename T>
struct thing
{
    T t;

    operator const T&() const 
    { 
        return t;
    }
    const T& get() const 
    { 
        return t; 
    }
};

然后您可以像这样呼叫fun

fun(b.get());

答案 1 :(得分:2)

Template argument deduction不考虑隐式转换。

  

类型推导不考虑隐式转换(上面列出的类型调整除外):这是overload resolution的工作,以后会发生。

然后给定fun(b);,将无法调用模板fun,因为无法推导T

您可以显式指定模板参数,然后可以进行重载解析和隐式转换。

fun<int>(b);

LIVE

相关问题