Partial specialization does not use any of its template parameters
I'm trying to implement tuples with template metaprogramming, but am having problems with the indexing function get. The implementation of Tuple type is this:
template<typename A, typename... B>
class Tuple : Tuple<B...> {
private:
A val;
public:
using Base = Tuple<B...>;
Base* base() {
return static_cast<Base*>(this);
}
const Base* base() const {
return static_cast<const Base*>(this);
}
Tuple(A a, B... b): Base(b...), val(a) { }
A first() {
return val;
}
};
template<class A>
class Tuple<A> {
private:
A val;
public:
Tuple(A a): val{a} {}
A first() {
return val;
}
};
The implementation of get structure is:
template<int N, class... A>
struct get {
select<N,A...> operator()(Tuple<A...> t) {
return get<N-1>()(t.base());
}
};
template<class R, class... A>
struct get<0> {
R operator()(Tuple<R, A...> t) {
return t.first();
}
};
This is the error compiler is giving me:
tuple.cpp:53:8: error: partial specialization of 'get' does not use any of its template parameters
struct get<0> {
^
1 error generated.
Why am I getting this error? How can I correct it?
Note: select<N,A...> is a type function which selects type at Nth index from A.
c++ c++11 variadic-templates template-meta-programming template-specialization
add a comment |
I'm trying to implement tuples with template metaprogramming, but am having problems with the indexing function get. The implementation of Tuple type is this:
template<typename A, typename... B>
class Tuple : Tuple<B...> {
private:
A val;
public:
using Base = Tuple<B...>;
Base* base() {
return static_cast<Base*>(this);
}
const Base* base() const {
return static_cast<const Base*>(this);
}
Tuple(A a, B... b): Base(b...), val(a) { }
A first() {
return val;
}
};
template<class A>
class Tuple<A> {
private:
A val;
public:
Tuple(A a): val{a} {}
A first() {
return val;
}
};
The implementation of get structure is:
template<int N, class... A>
struct get {
select<N,A...> operator()(Tuple<A...> t) {
return get<N-1>()(t.base());
}
};
template<class R, class... A>
struct get<0> {
R operator()(Tuple<R, A...> t) {
return t.first();
}
};
This is the error compiler is giving me:
tuple.cpp:53:8: error: partial specialization of 'get' does not use any of its template parameters
struct get<0> {
^
1 error generated.
Why am I getting this error? How can I correct it?
Note: select<N,A...> is a type function which selects type at Nth index from A.
c++ c++11 variadic-templates template-meta-programming template-specialization
I think you can resolve it if you simply changetemplate <class R, class ... A>totemplate <>and changeTuple<R, A...>toTuple<0>.
– Nir Friedman
Mar 16 '18 at 19:59
add a comment |
I'm trying to implement tuples with template metaprogramming, but am having problems with the indexing function get. The implementation of Tuple type is this:
template<typename A, typename... B>
class Tuple : Tuple<B...> {
private:
A val;
public:
using Base = Tuple<B...>;
Base* base() {
return static_cast<Base*>(this);
}
const Base* base() const {
return static_cast<const Base*>(this);
}
Tuple(A a, B... b): Base(b...), val(a) { }
A first() {
return val;
}
};
template<class A>
class Tuple<A> {
private:
A val;
public:
Tuple(A a): val{a} {}
A first() {
return val;
}
};
The implementation of get structure is:
template<int N, class... A>
struct get {
select<N,A...> operator()(Tuple<A...> t) {
return get<N-1>()(t.base());
}
};
template<class R, class... A>
struct get<0> {
R operator()(Tuple<R, A...> t) {
return t.first();
}
};
This is the error compiler is giving me:
tuple.cpp:53:8: error: partial specialization of 'get' does not use any of its template parameters
struct get<0> {
^
1 error generated.
Why am I getting this error? How can I correct it?
Note: select<N,A...> is a type function which selects type at Nth index from A.
c++ c++11 variadic-templates template-meta-programming template-specialization
I'm trying to implement tuples with template metaprogramming, but am having problems with the indexing function get. The implementation of Tuple type is this:
template<typename A, typename... B>
class Tuple : Tuple<B...> {
private:
A val;
public:
using Base = Tuple<B...>;
Base* base() {
return static_cast<Base*>(this);
}
const Base* base() const {
return static_cast<const Base*>(this);
}
Tuple(A a, B... b): Base(b...), val(a) { }
A first() {
return val;
}
};
template<class A>
class Tuple<A> {
private:
A val;
public:
Tuple(A a): val{a} {}
A first() {
return val;
}
};
The implementation of get structure is:
template<int N, class... A>
struct get {
select<N,A...> operator()(Tuple<A...> t) {
return get<N-1>()(t.base());
}
};
template<class R, class... A>
struct get<0> {
R operator()(Tuple<R, A...> t) {
return t.first();
}
};
This is the error compiler is giving me:
tuple.cpp:53:8: error: partial specialization of 'get' does not use any of its template parameters
struct get<0> {
^
1 error generated.
Why am I getting this error? How can I correct it?
Note: select<N,A...> is a type function which selects type at Nth index from A.
c++ c++11 variadic-templates template-meta-programming template-specialization
c++ c++11 variadic-templates template-meta-programming template-specialization
edited Nov 21 '18 at 14:02
max66
35.1k73763
35.1k73763
asked Mar 16 '18 at 19:41
sagasaga
513315
513315
I think you can resolve it if you simply changetemplate <class R, class ... A>totemplate <>and changeTuple<R, A...>toTuple<0>.
– Nir Friedman
Mar 16 '18 at 19:59
add a comment |
I think you can resolve it if you simply changetemplate <class R, class ... A>totemplate <>and changeTuple<R, A...>toTuple<0>.
– Nir Friedman
Mar 16 '18 at 19:59
I think you can resolve it if you simply change
template <class R, class ... A> to template <> and change Tuple<R, A...> to Tuple<0>.– Nir Friedman
Mar 16 '18 at 19:59
I think you can resolve it if you simply change
template <class R, class ... A> to template <> and change Tuple<R, A...> to Tuple<0>.– Nir Friedman
Mar 16 '18 at 19:59
add a comment |
2 Answers
2
active
oldest
votes
Your get's primary template is:
template<int N, class... A>
struct get{ ... };
your get's partial specialization is:
template<class R, class... A>
struct get<0>{ ... };
The specialization is receiving a single template argument, i.e.: 0, but the primary template above takes two template parameters:
- the non-type template parameter
N. - the variadic type parameter
A.
Besides, how can R be deduced?
Specializing get instead as:
template<class R, class... A>
struct get<0, R, A...>{ ... };
will make possible R to be deduced: it will be deduced to the type of the first element of the passed variadic argument. For example, in:
get<0, int, float, double> foo;
R will be deduced to int.
add a comment |
Maybe you have to partial specialize get as follows
template<class R, class... A>
struct get<0, R, A...> {
R operator()(Tuple<R, A...> t) {
return t.first();
}
};
I mean... get<0, R, A...>, not get<0>
But you have also to modify the main get to call the following call with the correct type list, so
template<int N, typename A0, typename ... As>
struct get {
auto operator()(Tuple<A0, As...> t) {
return get<N-1, As...>()(t.base());
}
};
Otherwise you can also demand the types management to a template version of the operator() and maintain only the int N value for get
template <int N>
struct get
{
template <typename Tpl>
auto operator() (Tpl t)
-> decltype( get<N-1>()(t.base()) )
{ return get<N-1>()(t.base()); }
};
template<>
struct get<0>
{
template <typename Tpl>
auto operator() (Tpl t)
-> decltype ( t.first() )
{ return t.first(); }
};
Starting from C++14 you can avoid the decltype() part.
Off topic suggestion: avoid the use of names that can collide with std namespace names.
Maybe myGet and myTuple instead of get and Tuple.
Otherwise you can put all in a personal namespace (so myNs::get and myNs::Tuple.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f49328379%2fpartial-specialization-does-not-use-any-of-its-template-parameters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your get's primary template is:
template<int N, class... A>
struct get{ ... };
your get's partial specialization is:
template<class R, class... A>
struct get<0>{ ... };
The specialization is receiving a single template argument, i.e.: 0, but the primary template above takes two template parameters:
- the non-type template parameter
N. - the variadic type parameter
A.
Besides, how can R be deduced?
Specializing get instead as:
template<class R, class... A>
struct get<0, R, A...>{ ... };
will make possible R to be deduced: it will be deduced to the type of the first element of the passed variadic argument. For example, in:
get<0, int, float, double> foo;
R will be deduced to int.
add a comment |
Your get's primary template is:
template<int N, class... A>
struct get{ ... };
your get's partial specialization is:
template<class R, class... A>
struct get<0>{ ... };
The specialization is receiving a single template argument, i.e.: 0, but the primary template above takes two template parameters:
- the non-type template parameter
N. - the variadic type parameter
A.
Besides, how can R be deduced?
Specializing get instead as:
template<class R, class... A>
struct get<0, R, A...>{ ... };
will make possible R to be deduced: it will be deduced to the type of the first element of the passed variadic argument. For example, in:
get<0, int, float, double> foo;
R will be deduced to int.
add a comment |
Your get's primary template is:
template<int N, class... A>
struct get{ ... };
your get's partial specialization is:
template<class R, class... A>
struct get<0>{ ... };
The specialization is receiving a single template argument, i.e.: 0, but the primary template above takes two template parameters:
- the non-type template parameter
N. - the variadic type parameter
A.
Besides, how can R be deduced?
Specializing get instead as:
template<class R, class... A>
struct get<0, R, A...>{ ... };
will make possible R to be deduced: it will be deduced to the type of the first element of the passed variadic argument. For example, in:
get<0, int, float, double> foo;
R will be deduced to int.
Your get's primary template is:
template<int N, class... A>
struct get{ ... };
your get's partial specialization is:
template<class R, class... A>
struct get<0>{ ... };
The specialization is receiving a single template argument, i.e.: 0, but the primary template above takes two template parameters:
- the non-type template parameter
N. - the variadic type parameter
A.
Besides, how can R be deduced?
Specializing get instead as:
template<class R, class... A>
struct get<0, R, A...>{ ... };
will make possible R to be deduced: it will be deduced to the type of the first element of the passed variadic argument. For example, in:
get<0, int, float, double> foo;
R will be deduced to int.
edited Mar 16 '18 at 20:11
answered Mar 16 '18 at 19:57
ネロクネロク
10.5k32140
10.5k32140
add a comment |
add a comment |
Maybe you have to partial specialize get as follows
template<class R, class... A>
struct get<0, R, A...> {
R operator()(Tuple<R, A...> t) {
return t.first();
}
};
I mean... get<0, R, A...>, not get<0>
But you have also to modify the main get to call the following call with the correct type list, so
template<int N, typename A0, typename ... As>
struct get {
auto operator()(Tuple<A0, As...> t) {
return get<N-1, As...>()(t.base());
}
};
Otherwise you can also demand the types management to a template version of the operator() and maintain only the int N value for get
template <int N>
struct get
{
template <typename Tpl>
auto operator() (Tpl t)
-> decltype( get<N-1>()(t.base()) )
{ return get<N-1>()(t.base()); }
};
template<>
struct get<0>
{
template <typename Tpl>
auto operator() (Tpl t)
-> decltype ( t.first() )
{ return t.first(); }
};
Starting from C++14 you can avoid the decltype() part.
Off topic suggestion: avoid the use of names that can collide with std namespace names.
Maybe myGet and myTuple instead of get and Tuple.
Otherwise you can put all in a personal namespace (so myNs::get and myNs::Tuple.
add a comment |
Maybe you have to partial specialize get as follows
template<class R, class... A>
struct get<0, R, A...> {
R operator()(Tuple<R, A...> t) {
return t.first();
}
};
I mean... get<0, R, A...>, not get<0>
But you have also to modify the main get to call the following call with the correct type list, so
template<int N, typename A0, typename ... As>
struct get {
auto operator()(Tuple<A0, As...> t) {
return get<N-1, As...>()(t.base());
}
};
Otherwise you can also demand the types management to a template version of the operator() and maintain only the int N value for get
template <int N>
struct get
{
template <typename Tpl>
auto operator() (Tpl t)
-> decltype( get<N-1>()(t.base()) )
{ return get<N-1>()(t.base()); }
};
template<>
struct get<0>
{
template <typename Tpl>
auto operator() (Tpl t)
-> decltype ( t.first() )
{ return t.first(); }
};
Starting from C++14 you can avoid the decltype() part.
Off topic suggestion: avoid the use of names that can collide with std namespace names.
Maybe myGet and myTuple instead of get and Tuple.
Otherwise you can put all in a personal namespace (so myNs::get and myNs::Tuple.
add a comment |
Maybe you have to partial specialize get as follows
template<class R, class... A>
struct get<0, R, A...> {
R operator()(Tuple<R, A...> t) {
return t.first();
}
};
I mean... get<0, R, A...>, not get<0>
But you have also to modify the main get to call the following call with the correct type list, so
template<int N, typename A0, typename ... As>
struct get {
auto operator()(Tuple<A0, As...> t) {
return get<N-1, As...>()(t.base());
}
};
Otherwise you can also demand the types management to a template version of the operator() and maintain only the int N value for get
template <int N>
struct get
{
template <typename Tpl>
auto operator() (Tpl t)
-> decltype( get<N-1>()(t.base()) )
{ return get<N-1>()(t.base()); }
};
template<>
struct get<0>
{
template <typename Tpl>
auto operator() (Tpl t)
-> decltype ( t.first() )
{ return t.first(); }
};
Starting from C++14 you can avoid the decltype() part.
Off topic suggestion: avoid the use of names that can collide with std namespace names.
Maybe myGet and myTuple instead of get and Tuple.
Otherwise you can put all in a personal namespace (so myNs::get and myNs::Tuple.
Maybe you have to partial specialize get as follows
template<class R, class... A>
struct get<0, R, A...> {
R operator()(Tuple<R, A...> t) {
return t.first();
}
};
I mean... get<0, R, A...>, not get<0>
But you have also to modify the main get to call the following call with the correct type list, so
template<int N, typename A0, typename ... As>
struct get {
auto operator()(Tuple<A0, As...> t) {
return get<N-1, As...>()(t.base());
}
};
Otherwise you can also demand the types management to a template version of the operator() and maintain only the int N value for get
template <int N>
struct get
{
template <typename Tpl>
auto operator() (Tpl t)
-> decltype( get<N-1>()(t.base()) )
{ return get<N-1>()(t.base()); }
};
template<>
struct get<0>
{
template <typename Tpl>
auto operator() (Tpl t)
-> decltype ( t.first() )
{ return t.first(); }
};
Starting from C++14 you can avoid the decltype() part.
Off topic suggestion: avoid the use of names that can collide with std namespace names.
Maybe myGet and myTuple instead of get and Tuple.
Otherwise you can put all in a personal namespace (so myNs::get and myNs::Tuple.
edited Mar 16 '18 at 20:15
answered Mar 16 '18 at 19:54
max66max66
35.1k73763
35.1k73763
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f49328379%2fpartial-specialization-does-not-use-any-of-its-template-parameters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I think you can resolve it if you simply change
template <class R, class ... A>totemplate <>and changeTuple<R, A...>toTuple<0>.– Nir Friedman
Mar 16 '18 at 19:59