具有嵌套非专业化类型的模板专业化

发布于 2024-12-02 19:00:41 字数 1663 浏览 1 评论 0原文

我在制定嵌套部分模板专业化的语法时遇到问题。我认为无论如何这是正确的表达方式。我想要的是一个返回强制转换值的 as() 函数。在大多数情况下,static_cast 可以正常工作,因此我有一个通用版本可以做到这一点,但在某些情况下我想要具体一点。我遇到的麻烦是当尝试使用通用的typename返回两个相似的模板化类类型时。

template<typename ClassType>
class Generic
{
public:
    // Constructors/etc excluded

    template<typename CastType>
    CastType as() const;

private:
    ClassType m_value;
};

// Templated version:
template<typename ClassType> template<typename CastType> inline
CastType Generic<ClassType>::as<CastType>() const
{
    return static_cast<CastType>(m_value);
}

这就是设置。实际上我不是 100% 确定这是否是最好的方法,但它在 GCC 中编译并且似乎可以工作,所以..无论如何。现在我想专注于另一种模板类型(在本例中为 Eigen::Matrix ——但也许是 std::vector 或其他类型可能会及时使用,即从 std::vector 转换为部分模板化的 std::list):

template<> template<typename CastType> inline
CastType Generic<Eigen::Matrix<CastType,4,1> >::as<CastType>() const
{
    return m_value[0];
}

这有什么意义吗?稍微不同的版本怎么样,我采用不同大小的 Eigen::Matrix 并专门处理它们?

template<> template<typename CastType> inline
Eigen::Matrix<CastType,3,1> Generic<Eigen::Matrix<CastType,4,1> >::as<Eigen::Matrix<CastType,3,1>() const
{
    return Eigen::Matrix<CastType,3,1>( m_value[0], m_value[1], m_value[2] );
}

我知道上面的两个代码位不起作用,而且语法可能很糟糕,这就是我正在努力解决的问题。如果这是重复的,请原谅。我查看了几个类似的问题,但似乎没有一个与此相关,或者我只是没有看到它。

I'm having trouble working out the syntax for a nested partial template specialization. I think that's the right way of putting it anyway. What I want is an as() function which returns a casted value. In most cases static_cast will work fine so I have a generic version which does that, but in some cases I want to get specific. The trouble I'm having is when trying to return two similar templated class types, using a common typename.

template<typename ClassType>
class Generic
{
public:
    // Constructors/etc excluded

    template<typename CastType>
    CastType as() const;

private:
    ClassType m_value;
};

// Templated version:
template<typename ClassType> template<typename CastType> inline
CastType Generic<ClassType>::as<CastType>() const
{
    return static_cast<CastType>(m_value);
}

That's the set-up. Actually I'm not 100% sure if that's the best way to do it, but it compiles in GCC and seems to work, so.. anyway. Now I want to specialize with another templated type (in this case, Eigen::Matrix<T,4,1> -- but perhaps std::vector or another as well might be used in time, i.e. to cast from a std::vector<T> to a std::list<T>) that's partialy templated:

template<> template<typename CastType> inline
CastType Generic<Eigen::Matrix<CastType,4,1> >::as<CastType>() const
{
    return m_value[0];
}

Does this make any sense? What about a slightly different version where I take Eigen::Matrix of differing sizes and handle them specially?

template<> template<typename CastType> inline
Eigen::Matrix<CastType,3,1> Generic<Eigen::Matrix<CastType,4,1> >::as<Eigen::Matrix<CastType,3,1>() const
{
    return Eigen::Matrix<CastType,3,1>( m_value[0], m_value[1], m_value[2] );
}

I know the above two code bits don't work and the syntax is probably horrible, this is what I'm trying to work out. Forgive if this is a duplicate. I looked at several similar questions but none seemed quite to be about this, or I just didn't see it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凹づ凸ル 2024-12-09 19:00:41

由于函数不能部分特化,因此我们部分特化一个 functionoid-thingy,并使函数仅使用专门的类。

//generic version
template<typename ClassType, typename CastType> class As { 
public: CastType operator()(const ClassType& b)
    {return static_cast<CastType>(b);}
};
//specialization
template<> class As<int, char* > { 
public: char* operator()(const int& b)
    {throw b;} //so we know it worked
};

//generic class 
template<typename ClassType>
class Generic
{
public:
    Generic() {m_value=0;} //codepad made me put this in
    // Constructors/etc excluded

    template<typename CastType>
    CastType as() const; //as function

private:
    ClassType m_value;
};

// as function simply grabs the right "As" class and uses that
template<typename ClassType> template<typename CastType> inline
CastType Generic<ClassType>::as() const
{
    As<ClassType, CastType> impl;
    return impl(m_value);
}

//main, confirming that it compiles and runs (though I didn't check b...)
int main() {
    Generic<int> gint;
    float b = gint.as<float>();
    char* crash = gint.as<char*>();
}

代码位于:http://codepad.org/oVgCxTMI
结果:

未捕获的 int 类型异常
已中止。

Since a function can't be partially specialize, we partially specialize a functionoid-thingy instead, and make the function simply use the specialized class.

//generic version
template<typename ClassType, typename CastType> class As { 
public: CastType operator()(const ClassType& b)
    {return static_cast<CastType>(b);}
};
//specialization
template<> class As<int, char* > { 
public: char* operator()(const int& b)
    {throw b;} //so we know it worked
};

//generic class 
template<typename ClassType>
class Generic
{
public:
    Generic() {m_value=0;} //codepad made me put this in
    // Constructors/etc excluded

    template<typename CastType>
    CastType as() const; //as function

private:
    ClassType m_value;
};

// as function simply grabs the right "As" class and uses that
template<typename ClassType> template<typename CastType> inline
CastType Generic<ClassType>::as() const
{
    As<ClassType, CastType> impl;
    return impl(m_value);
}

//main, confirming that it compiles and runs (though I didn't check b...)
int main() {
    Generic<int> gint;
    float b = gint.as<float>();
    char* crash = gint.as<char*>();
}

code at: http://codepad.org/oVgCxTMI
results:

uncaught exception of type int
Aborted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文