具有多个模板参数错误的模板部分特化

发布于 2024-12-11 23:38:20 字数 2481 浏览 0 评论 0原文

当我在具有一个模板参数的类上使用模板部分特化时,我可以专门化这样的方法:

#include <cstdlib>

template< std::size_t Dim >
class Test
{
public:
  int foo();
};

template< std::size_t Dim >
inline int Test< Dim >::foo()
{
  return 0;
}

template<>
inline int Test< 1 >::foo()
{
  return 1;
}

int main()
{
  Test< 2 > wTest2;
  Test< 1 > wTest1;
  wTest2.foo();
  wTest1.foo();
  return 0;
}

方法 foo 专门用于 Dim = 1。但是一旦我向我的类添加模板参数,就像这样

#include <cstdlib>

template< typename T, std::size_t Dim >
class Test
{
public:
  int foo();
};

template< typename T, std::size_t Dim >
inline int Test< T, Dim >::foo()
{
  return 0;
}

template< typename T >
inline int Test< T, 1 >::foo()
{
  return 1;
}

int main()
{
  Test< double, 2 > wTest2;
  Test< double, 1 > wTest1;
  wTest2.foo();
  wTest1.foo();
  return 0;
}

: (VS2010 的)抱怨这些错误:

1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(20): error C3860: template argument list following class template name must list parameters in the order used in template parameter list
1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(20): error C2995: 'int Test<T,Dim>::foo(void)' : function template has already been defined
1>          c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(7) : see declaration of 'Test<T,Dim>::foo'
1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(20): error C2976: 'Test<T,Dim>' : too few template arguments
1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(26): error C2264: 'Test<T,Dim>::foo' : error in function definition or declaration; function not called
1>          with
1>          [
1>              T=double,
1>              Dim=2
1>          ]
1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(27): error C2264: 'Test<T,Dim>::foo' : error in function definition or declaration; function not called
1>          with
1>          [
1>              T=double,
1>              Dim=1
1>          ]
1>
1>Build FAILED.

在我看来,没有任何歧义,编译器应该能够解决所有问题并像单参数情况一样工作。

如果 C++ 不支持此功能,请解释原因。

When I use template partial specialization on a class with one template argument, I can specialize a method like this:

#include <cstdlib>

template< std::size_t Dim >
class Test
{
public:
  int foo();
};

template< std::size_t Dim >
inline int Test< Dim >::foo()
{
  return 0;
}

template<>
inline int Test< 1 >::foo()
{
  return 1;
}

int main()
{
  Test< 2 > wTest2;
  Test< 1 > wTest1;
  wTest2.foo();
  wTest1.foo();
  return 0;
}

The method foo is specialized for Dim = 1. But as soon as I add a template argument to my class, like this:

#include <cstdlib>

template< typename T, std::size_t Dim >
class Test
{
public:
  int foo();
};

template< typename T, std::size_t Dim >
inline int Test< T, Dim >::foo()
{
  return 0;
}

template< typename T >
inline int Test< T, 1 >::foo()
{
  return 1;
}

int main()
{
  Test< double, 2 > wTest2;
  Test< double, 1 > wTest1;
  wTest2.foo();
  wTest1.foo();
  return 0;
}

The compiler (of VS2010) complains with these errors:

1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(20): error C3860: template argument list following class template name must list parameters in the order used in template parameter list
1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(20): error C2995: 'int Test<T,Dim>::foo(void)' : function template has already been defined
1>          c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(7) : see declaration of 'Test<T,Dim>::foo'
1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(20): error C2976: 'Test<T,Dim>' : too few template arguments
1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(26): error C2264: 'Test<T,Dim>::foo' : error in function definition or declaration; function not called
1>          with
1>          [
1>              T=double,
1>              Dim=2
1>          ]
1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(27): error C2264: 'Test<T,Dim>::foo' : error in function definition or declaration; function not called
1>          with
1>          [
1>              T=double,
1>              Dim=1
1>          ]
1>
1>Build FAILED.

The way I see this, there is no ambiguity and the compiler should be able to resolve everything and work just like the one argument case.

If this is not supported in C++, please explain why.

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

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

发布评论

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

评论(2

羞稚 2024-12-18 23:38:20

你不能部分特化函数 - 这包括成员函数。你只能部分特化整个类:(

template< typename T, std::size_t Dim >
class Test
{
public:
  int foo()
  {
    return 0;
  }
};

template< typename T >
class test< T, 1 >
{
public:
  int foo()
  {
    return 1;
  }
};

我在这里定义了内联函数;当然没有必要。)

You cannot partially specialise functions – this includes member functions. You can only partially specialise the whole class:

template< typename T, std::size_t Dim >
class Test
{
public:
  int foo()
  {
    return 0;
  }
};

template< typename T >
class test< T, 1 >
{
public:
  int foo()
  {
    return 1;
  }
};

(I’ve defined the functions inline here; that of course isn’t necessary.)

稳稳的幸福 2024-12-18 23:38:20

编辑,因为我还不能发表评论(50 代表嘿)...

Philippe,今天早上回应你的评论,根据标准,你不能部分专业化类模板的成员,你只能完全专业化它们(无论是类模板、函数、函数模板等...)。在第一个示例中,您完全专业化了成员函数 foo。在你的第二个例子中,你是部分专业化的,这就是它无法编译的原因。您可以通过这种方式完全专业化它:

template< >
inline int Test< int, 2 >::foo()
{...}

虽然 Konrad 的代码片段完全合法,但我不确定提供的关于 Philippe 的代码无法编译的原因是否正确。 (尽管,正如康拉德提到的,你不能部分特化函数模板)。

在 Philippe 的代码中,当前的问题是我们声明的是类模板而不是函数模板。因此,为了使部分专业化定义合法,需要部分类模板专业化声明。

#include <cstdlib>

template< typename T, std::size_t Dim >
class Test
{
public:
    int foo();
};

template < typename T >
class Test < T, 1 >
{
public:
    int foo();
};


template< typename T, std::size_t Dim >
inline int Test< T, Dim >::foo()
{
    return 0;
}

template< typename T >
inline int Test< T, 1 >::foo()
{
    return 1;
}

int main()
{
    Test< double, 2 > wTest2;
    Test< int, 1 > wTest1;
    wTest2.foo();
    wTest1.foo();
    return 0;
}

Editing since I cannot post comments yet (50 rep heh)...

Philippe, in response to your comment this morning, according to the standard you cannot partially specialize a member of a class template, you can only fully specialize them (whether it be a class template, a function, a function template, etc...). In your first example, you are fully specializing the member function foo. In your second example, you are partially specializing, reason why it will not compile. You can fully specialize it this way:

template< >
inline int Test< int, 2 >::foo()
{...}

Although Konrad's code snipet is perfectly legal, I'm not sure the reason provided as to why Philippe's code doesn't compile is correct. (Although, as Konrad mentionned, you cannot partially specialize a function template).

The issue at hand, in Philippe's code, is that we are declaring a class template and not a function template. Hence, a partial class template specialization declaration is needed for the partial specialization definition to be legal.

#include <cstdlib>

template< typename T, std::size_t Dim >
class Test
{
public:
    int foo();
};

template < typename T >
class Test < T, 1 >
{
public:
    int foo();
};


template< typename T, std::size_t Dim >
inline int Test< T, Dim >::foo()
{
    return 0;
}

template< typename T >
inline int Test< T, 1 >::foo()
{
    return 1;
}

int main()
{
    Test< double, 2 > wTest2;
    Test< int, 1 > wTest1;
    wTest2.foo();
    wTest1.foo();
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文