C++模板专用获取器

C++ template specialized getters

本文关键字:获取 专用 C++      更新时间:2023-10-16

我目前正在编写一个使用NURBS surfaces的程序,您可以在其中执行两个方向(UV)的算法。为了避免代码重复,我尝试使用模板,但我没有使用它们的经验。这里有一个小例子来说明我想做的事情:

#include <iostream>
enum class Dir {
    U, V
};
struct Foo {
    unsigned cu, cv;
    Foo(unsigned cu, unsigned cv) : cu(cu), cv(cv) {};
    template<Dir>
    const Dir otherDir();
    template<>
    const Dir otherDir<Dir::V>() {
        return Dir::U;
    }
    template<>
    const Dir otherDir<Dir::U>() {
        return Dir::V;
    }
    template<Dir>
    unsigned count();
    template<>
    unsigned count<Dir::U>() {
        return cu;
    }
    template<>
    unsigned count<Dir::V>() {
        return cv;
    }
    template<Dir d>
    unsigned totalCount() {
        auto c = count<d>();
        auto cOther = count<otherDir<d>()>();
        return c * cOther;
    }
};
int main() {
    Foo f(3,2);
    std::cout << (f.count<Dir::U>() == 3) << std::endl;
    std::cout << (f.otherDir<Dir::U>() == Dir::V) << std::endl;
    std::cout << f.totalCount<Dir::U>() << std::endl;
}

但由于 main 的最后一行(VS2015,但我认为这不是编译器的错),这无法编译:

1>...main.cpp(42): error C2672: 'Foo::count': no matching overloaded function found
1>...main.cpp(52): note: see reference to function template instantiation 'unsigned int Foo::totalCount<Dir::U>(void)' being compiled
1>...main.cpp(42): error C2975: 'unnamed-parameter': invalid template argument for 'Foo::count', expected compile-time constant expression
1>...main.cpp(27): note: see declaration of 'unnamed-parameter'
1>...main.cpp(43): error C3536: 'cOther': cannot be used before it is initialized

我接近上述功能的唯一方法是将主要方向和其他方向指定为模板参数,如下所示:

struct Foo {
    ...
    template<Dir d, Dir otherD>
    unsigned totalCount() {
        auto c = count<d>();
        auto cOther = count<otherD>();
        return c * cOther;
    }
};
int main() {
    Foo f(3,2);
    std::cout << f.totalCount<Dir::U, Dir::V>() << std::endl;
}

但这似乎不是很优雅。

otherDir<d>()不是constexpr,不能在模板参数(count<otherDir<d>()>())中使用。

您可以向该方法添加constexpr(和static),或者使用旧结构来处理它:

template <Dir> struct otherDir;
template<>
struct otherDir<Dir::U>
{
    static constexpr Dir value = Dir::V;
};
template<>
struct otherDir<Dir::V>
{
    static constexpr Dir value = Dir::U;
};

演示

问题可能在这里:

auto cOther = count<otherDir<d>()>();

模板在编译时"解析"。您应该将constexpr用于otherDir<d>(),因为只是简单的const并不意味着可以在编译时计算该方法。

更传统的方法是使用结构otherDir而不是方法。创建结构模板,两个实例化将带有static const value = VU

或者,您可以将枚举替换为空结构。

或者,更好的

是,您可以尝试在没有模板的情况下实现它,并为维度创建类,每个维度都有一个对象。