【问题标题】:Implicit conversion operator for templated types not automatically determined未自动确定的模板类型的隐式转换运算符
【发布时间】:2019-08-08 14:28:05
【问题描述】:

我有一个带有隐式转换运算符的模板类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;
}

使用thing&lt;int&gt; 调用fun(const int&amp;),编译器能够计算出调用隐式转换运算符,以便将const T&amp;(在本例中为const int&amp;)传递给fun(const int&amp;)

但是,对于thing&lt;B&lt;int&gt;&gt;,编译器无法确定我期望调用fun(const B&lt;T&gt;&amp;)

我如何帮助编译器解决这个问题b 显式转换为const B&lt;int&gt;&amp;(例如使用static_cast&lt;const B&lt;int&gt;&amp;&gt;(b))?

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

【问题讨论】:

  • 你基本上不能,这不是模板的工作方式。他们不进行转换。

标签: c++ templates c++17


【解决方案1】:

如何在不将 b 转换为 const B&lt;int&gt;&amp; 的情况下帮助编译器解决这个问题?

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

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

template <typename T>
struct thing
{
    T t;

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

然后你就可以拨打funlike

fun(b.get());

【讨论】:

  • 所以,我不能部分专注于B 或类似的东西?但我可以为fun() 创建 10 个重载,对吗?
  • @j00hi 您不能部分专门化函数。你可以添加 10 个具体的函数重载。
【解决方案2】:

Template argument deduction 不考虑隐式转换。

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

那么给定fun(b);,模板fun不能被调用,因为T不能被推导出来。

您可以显式指定模板参数,然后重载解析和隐式转换都可以正常工作。

fun<int>(b);

LIVE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-16
    • 2018-01-25
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多