使用转换运算符但显式转换有效时,模板推导失败

时间:2018-03-30 21:11:00

标签: c++ templates template-deduction conversion-operator swizzle

我尝试使用模板编程在C ++中实现swizzle向量。使用swizzle矢量我的意思是类似于hlsl和glsl向量的向量,例如,如果你有一个向量v = (1,2,3,4)并且做v.xxyz它会产生向量(1,1,2,3)。

这涉及一个类似于下面给出的例子的数据结构,但是我删除了一堆东西以产生一个最小的工作示例。

#include <iostream>
template <typename T>
class vec2
{
public:
    template<unsigned a, unsigned b>
    class swizzle
    {
    public:
        T v[2];
    public:
        operator vec2() { return { v[a], v[b] }; }
    };

public:
    union
    {
        struct
        {
            T x, y;
        };
        swizzle<0, 0> xx;
        swizzle<0, 1> xy;
        swizzle<1, 0> yx;
        swizzle<1, 1> yy;
        T v[2];
    };
};

template<typename T>
void Foo(const vec2<T>& bar)
{
    std::cout << bar.x << ", " << bar.y << "\n";
}

void Bar(const vec2<float> bar)
{
    std::cout << bar.x << ", " << bar.y << "\n";
}

int main()
{
    vec2<float> v = { 1,2 };
    Foo(v.xx); //Does not compile. Template argument deduction fails.

    Foo((vec2<float>)v.xx); //Compiles. Prints "1, 1"

    Foo(v); //Compiles . Prints "1, 2"

    Bar(v.xx); //Compiles without having to explicitly cast it. Prints "1, 1"
    std::cin.get();
    return 0;
}

在上面的示例中,除非我明确地将swizzle强制转换为swizzle,否则使用vec2<float>类型的参数调用Foo不会编译,即使swizzle具有Foo转换运算符。处理模板时隐式转换不起作用吗?我的问题是,我希望能够同时使用Foo(v)Foo(v.xy)来致电dialog_fselect

0 个答案:

没有答案