C ++是否可以定义从pair <int,int =“”>到<float,float>的隐式转换?

时间:2016-03-10 11:07:27

标签: c++ templates grammar

template<typename type>
using point = std::pair<type, type>;

template<typename type>
point<type> operator-(point<type> a, point<type> b)
{
    return{ a.first - b.first, a.second - b.second };
}

int main() {
    point<float> a = { 0, 0 };
    point<int> b = { 1, 2 };
    point<float> p = a - b; // This does not compile.       
    return 0;
}

如何将point float和point int参数传递给我的“ - ”运算符,并将point int参数隐式转换为point float类型?

当然,我可以将该点声明为一个类,并使用构造函数来实现这一点。但这对我来说似乎很啰嗦。

2 个答案:

答案 0 :(得分:3)

注意:最初问题没有提及operator-,只是询问是否可以自动将point<int>转换为point<float>而不是类。我的回答解决了这个问题。我会留待它参考。 Colin Pitrat的答案解决了问题,因为它目前的表现更好。

已为您定义:std::pair有一个通用复制构造函数(即允许在可转换模板参数之间进行隐式转换的构造函数)

template< class U1, class U2 >
pair( const pair<U1, U2>& p );

(自{C ++ 14起为constexpr),只要pair<T1, U1>隐式转换为pair<T2, U2>,就允许使用T2初始化T1 }和U2U1

  

4)使用first初始化p.first,使用second初始化p.second。   (source

这意味着以下代码运行良好:

template<typename type> 
using point = std::pair<type, type>;

float dist(point<float> a, point<float> b)
{
    return pow(pow(a.first-b.first, 2) + pow(a.second - b.second, 2), 0.5);
}

int main() {
    std::cout << dist(point<int>{ 0, 0 }, point<int>{ 1, 1 });
    return 0;
}

答案 1 :(得分:2)

我认为您的operator-实际上是这样写的(使用type而不是float以及使用firstsecond代替x }和y

template<typename type>
point<type> operator-(point<type> a, point<type> b)
{
    return{ a.first - b.first, a.second - b.second };
}

CompuChip在他的回答中谈到generalized copy constructor并不适合你的原因是编译器需要找出要实例化的函数,并且你用{{{{}来调用它。 1}}和point<float>有两个不同的point<int>

只有在首先找到匹配函数时才会查找将type转换为point<int>的通用复制构造函数(例如,如果存在非模板point<float>)。但这只是在找到匹配函数之后,因此在模板实例化之后,为时已晚!

对于常规类,您需要做的是定义与模板相关的函数,这些函数支持在类模板中作为朋友的所有参数的隐式类型转换。 (参见Scott Meyer的优秀着作&#34; Effective C ++&#34;第46页)

但是,在您使用operator-(point<float>, point<float>)的情况下,您无法执行此操作。

一个选项是使用两个模板参数定义std::pair,如下所示:

operator-

它的作用是定义一个运算符,它取两个不同模板参数的点并返回一个与template<typename t1, typename t2> auto operator-(point<t1> a, point<t2> b) -> point<decltype(a.first - b.first)> { return{ a.first - b.first, a.second - b.second }; } 相对应的类型的点,这将是&#34; natural&#34;一个你期待的。