C++ - 使用该方法的部分规范重载模板化类方法

发布于 2024-10-20 14:48:32 字数 1024 浏览 1 评论 0原文

堆栈溢出上已经有一些与此类似的问题,但似乎没有什么可以直接回答我的问题。如果我重新发布,我深表歉意。

我想用这些方法的部分模板特化来重载模板类的一些方法(带有 2 个模板参数)。我无法找出正确的语法,并且开始认为这是不可能的。我想我应该在这里发帖看看是否能得到确认。

示例代码如下:

template <typename T, typename U>
class Test
{
public:
    void Set( T t, U u ); 

    T m_T;
    U m_U;
};

// Fully templated method that should be used most of the time
template <typename T, typename U>
inline void Test<T,U>::Set( T t, U u )
{
    m_T=t;
    m_U=u;
}

// Partial specialisation that should only be used when U is a float.
// This generates compile errors
template <typename T>
inline void Test<T,float>::Set( T t, float u )
{
    m_T=t;
    m_U=u+0.5f;
}


int _tmain(int argc, _TCHAR* argv[])
{
    Test<int, int> testOne;    
    int a = 1;
    testOne.Set( a, a );

    Test<int, float> testTwo;    
    float f = 1.f;
    testTwo.Set( a, f );
}

我知道我可以编写整个类的部分特化,但这有点糟糕。这样的事情可能吗?

(我用的是VS2008) 编辑:这是编译错误 错误 C2244:“Test::Set”:无法将函数定义与现有声明匹配

谢谢:)

There are a few questions already similar to this already on stack overflow, but nothing that seemd to directly answer the question I have. I do apologise if I am reposting.

I'd like to overload a few methods of a templated class (with 2 template parameters) with a partial template specialisation of those methods. I haven't been able to figure out the correct syntax, and am starting to think that it's not possible. I thought I'd post here to see if I can get confirmation.

Example code to follow:

template <typename T, typename U>
class Test
{
public:
    void Set( T t, U u ); 

    T m_T;
    U m_U;
};

// Fully templated method that should be used most of the time
template <typename T, typename U>
inline void Test<T,U>::Set( T t, U u )
{
    m_T=t;
    m_U=u;
}

// Partial specialisation that should only be used when U is a float.
// This generates compile errors
template <typename T>
inline void Test<T,float>::Set( T t, float u )
{
    m_T=t;
    m_U=u+0.5f;
}


int _tmain(int argc, _TCHAR* argv[])
{
    Test<int, int> testOne;    
    int a = 1;
    testOne.Set( a, a );

    Test<int, float> testTwo;    
    float f = 1.f;
    testTwo.Set( a, f );
}

I know that I could write a partial specialisation of the entire class, but that kinda sucks. Is something like this possible?

(I'm using VS2008)
Edit: Here is the compile error
error C2244: 'Test::Set' : unable to match function definition to an existing declaration

Thanks :)

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

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

发布评论

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

评论(3

是伱的 2024-10-27 14:48:32

如果不定义类模板本身的部分特化,则无法部分特化成员函数。请注意,模板的部分特化仍然是模板,因此当编译器看到 Test 时,它期望类模板的部分特化。

--

C++ 标准 (2003) 中的 $14.5.4.3/1 说,

a的模板参数列表
类模板部分的成员
专业化应与
类的模板参数列表
模板部分特化。

成员的模板参数列表
类模板部分
专业化应与
类的模板参数列表
模板部分专业化。 A
类模板特化是
独特的模板。的成员
类模板部分特化
与成员无关
主模板。
类模板
部分专业化成员
以需要的方式使用
应定义定义;这
主要成员的定义
模板从不用作定义
对于类模板的成员
部分专业化。明确的
班级成员的专业化
模板部分特化是
以与
初级的明确专业化
模板。

然后标准本身给出了这个例子,

// primary template
template<class T, int I> struct A {
void f();
};
template<class T, int I> void A<T,I>::f() { }

// class template partial specialization
template<class T> struct A<T,2> {
void f();
void g();
void h();
};
// member of class template partial specialization
template<class T> void A<T,2>::g() { }

我希望标准中的引用和例子能够很好地回答你的问题。

You cannot partially specialize a member function without defining partial specialization of the class template itself. Note that partial specialization of a template is STILL a template, hence when the compiler sees Test<T, float>, it expects a partial specialization of the class template.

--

$14.5.4.3/1 from the C++ Standard (2003) says,

The template parameter list of a
member of a class template partial
specialization shall match the
template parameter list of the class
template partial specialization.
The
template argument list of a member of
a class template partial
specialization shall match the
template argument list of the class
template partial specialization. A
class template specialization is a
distinct template. The members of the
class template partial specialization
are unrelated to the members of the
primary template.
Class template
partial specialization members that
are used in a way that requires a
definition shall be defined; the
definitions of members of the primary
template are never used as definitions
for members of a class template
partial specialization. An explicit
specialization of a member of a class
template partial specialization is
declared in the same way as an
explicit specialization of the primary
template.

Then the Standard itself gives this example,

// primary template
template<class T, int I> struct A {
void f();
};
template<class T, int I> void A<T,I>::f() { }

// class template partial specialization
template<class T> struct A<T,2> {
void f();
void g();
void h();
};
// member of class template partial specialization
template<class T> void A<T,2>::g() { }

I hope the quotation from the Standard along with the example answers your question well.

萌化 2024-10-27 14:48:32

您所描绘的特定问题很简单:

template< class T >
inline T foo( T const& v ) { return v; }

template<>
float foo( float const& v ) { return v+0.5; }

然后从您的 Test::Set 实现中调用 foo

如果您想要完整的通用性,则类似地使用具有静态帮助器成员函数的帮助器类,并部分专门化该帮助器类。

干杯&呵呵,

The particular problem you're sketching is easy:

template< class T >
inline T foo( T const& v ) { return v; }

template<>
float foo( float const& v ) { return v+0.5; }

Then call foo from your Test::Set implementation.

If you want the full generality, then similarly use a helper class with static helper member functions, and partially specialize that helper class.

Cheers & hth.,

想你的星星会说话 2024-10-27 14:48:32

如果您不想在代码中引入额外的函数、方法或类,那么还有另一种解决部分专业化问题的方法。

#include <type_traits>

template <typename T1, typename T2>
class C
{
    void f(T1 t1);
}

template <typename T1, typename T2>
void C<T1, T2>::f(T1 t1)
{
    if (std::is_same<T2, float>::value)
    // Do sth
    else
    // Do sth
}

There's also another solution to the partial specialization problem, if you don't want to introduce additional functions, methods or classes to your code.

#include <type_traits>

template <typename T1, typename T2>
class C
{
    void f(T1 t1);
}

template <typename T1, typename T2>
void C<T1, T2>::f(T1 t1)
{
    if (std::is_same<T2, float>::value)
    // Do sth
    else
    // Do sth
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文