Non Deduced context for a non type parameter
I am reading C++ Templates (2nd edition) and this is a snippet from the book:
template<typename... Ts, int N>
void f(double (&)[N+1], Ts... ps) {return;}
It is specified in the book that the declaration above is useless because N cannot be specified or deduced.
I am trying to understand why something like the following is an error:
double arr[2];
f<int, double, 1>(arr, 1, 2.0);
When I compile the snippet above, I get the error that there is no matching function for call to f.
This compiles fine
template<typename... Ts, typename T>
void func(T value){};
func(1);
even though I have an additional parameter after a parameter pack.
Why does my specifying of the template arguments explicitly not match the arguments provided? Please help me understand this.
c++ c++11 c++14 c++17 variadic-templates
add a comment |
I am reading C++ Templates (2nd edition) and this is a snippet from the book:
template<typename... Ts, int N>
void f(double (&)[N+1], Ts... ps) {return;}
It is specified in the book that the declaration above is useless because N cannot be specified or deduced.
I am trying to understand why something like the following is an error:
double arr[2];
f<int, double, 1>(arr, 1, 2.0);
When I compile the snippet above, I get the error that there is no matching function for call to f.
This compiles fine
template<typename... Ts, typename T>
void func(T value){};
func(1);
even though I have an additional parameter after a parameter pack.
Why does my specifying of the template arguments explicitly not match the arguments provided? Please help me understand this.
c++ c++11 c++14 c++17 variadic-templates
@πάντα ῥεῖ - Hmmm...This compiles fine - template<typename... Ts, typename T> void func(T value){}; func(1); even though I have an additional parameter after a parameter pack. Once again, my question here is different from the one you have linked to as I am not asking the compiler to do the deduction but I am helping it with the deduction. Need to understand why that fails.
– Ashish Daggubatti
Dec 15 at 8:30
Clang gives this notice "candidate template ignored: invalid explicitly-specified argument for template parameter 'Ts'". The invocationf<int, double>(arr, 1, 2.0)
compiles succesfully! So isf(arr, 1, 2.0)
. So it seemsN
can be deduced, at least in g++ and clang++.
– CygnusX1
Dec 15 at 8:32
@CygnusX1....sorry my bad...i have edited the question....it is actually N+1 and not N....
– Ashish Daggubatti
Dec 15 at 8:39
add a comment |
I am reading C++ Templates (2nd edition) and this is a snippet from the book:
template<typename... Ts, int N>
void f(double (&)[N+1], Ts... ps) {return;}
It is specified in the book that the declaration above is useless because N cannot be specified or deduced.
I am trying to understand why something like the following is an error:
double arr[2];
f<int, double, 1>(arr, 1, 2.0);
When I compile the snippet above, I get the error that there is no matching function for call to f.
This compiles fine
template<typename... Ts, typename T>
void func(T value){};
func(1);
even though I have an additional parameter after a parameter pack.
Why does my specifying of the template arguments explicitly not match the arguments provided? Please help me understand this.
c++ c++11 c++14 c++17 variadic-templates
I am reading C++ Templates (2nd edition) and this is a snippet from the book:
template<typename... Ts, int N>
void f(double (&)[N+1], Ts... ps) {return;}
It is specified in the book that the declaration above is useless because N cannot be specified or deduced.
I am trying to understand why something like the following is an error:
double arr[2];
f<int, double, 1>(arr, 1, 2.0);
When I compile the snippet above, I get the error that there is no matching function for call to f.
This compiles fine
template<typename... Ts, typename T>
void func(T value){};
func(1);
even though I have an additional parameter after a parameter pack.
Why does my specifying of the template arguments explicitly not match the arguments provided? Please help me understand this.
c++ c++11 c++14 c++17 variadic-templates
c++ c++11 c++14 c++17 variadic-templates
edited Dec 15 at 8:39
asked Dec 15 at 7:52
Ashish Daggubatti
18810
18810
@πάντα ῥεῖ - Hmmm...This compiles fine - template<typename... Ts, typename T> void func(T value){}; func(1); even though I have an additional parameter after a parameter pack. Once again, my question here is different from the one you have linked to as I am not asking the compiler to do the deduction but I am helping it with the deduction. Need to understand why that fails.
– Ashish Daggubatti
Dec 15 at 8:30
Clang gives this notice "candidate template ignored: invalid explicitly-specified argument for template parameter 'Ts'". The invocationf<int, double>(arr, 1, 2.0)
compiles succesfully! So isf(arr, 1, 2.0)
. So it seemsN
can be deduced, at least in g++ and clang++.
– CygnusX1
Dec 15 at 8:32
@CygnusX1....sorry my bad...i have edited the question....it is actually N+1 and not N....
– Ashish Daggubatti
Dec 15 at 8:39
add a comment |
@πάντα ῥεῖ - Hmmm...This compiles fine - template<typename... Ts, typename T> void func(T value){}; func(1); even though I have an additional parameter after a parameter pack. Once again, my question here is different from the one you have linked to as I am not asking the compiler to do the deduction but I am helping it with the deduction. Need to understand why that fails.
– Ashish Daggubatti
Dec 15 at 8:30
Clang gives this notice "candidate template ignored: invalid explicitly-specified argument for template parameter 'Ts'". The invocationf<int, double>(arr, 1, 2.0)
compiles succesfully! So isf(arr, 1, 2.0)
. So it seemsN
can be deduced, at least in g++ and clang++.
– CygnusX1
Dec 15 at 8:32
@CygnusX1....sorry my bad...i have edited the question....it is actually N+1 and not N....
– Ashish Daggubatti
Dec 15 at 8:39
@πάντα ῥεῖ - Hmmm...This compiles fine - template<typename... Ts, typename T> void func(T value){}; func(1); even though I have an additional parameter after a parameter pack. Once again, my question here is different from the one you have linked to as I am not asking the compiler to do the deduction but I am helping it with the deduction. Need to understand why that fails.
– Ashish Daggubatti
Dec 15 at 8:30
@πάντα ῥεῖ - Hmmm...This compiles fine - template<typename... Ts, typename T> void func(T value){}; func(1); even though I have an additional parameter after a parameter pack. Once again, my question here is different from the one you have linked to as I am not asking the compiler to do the deduction but I am helping it with the deduction. Need to understand why that fails.
– Ashish Daggubatti
Dec 15 at 8:30
Clang gives this notice "candidate template ignored: invalid explicitly-specified argument for template parameter 'Ts'". The invocation
f<int, double>(arr, 1, 2.0)
compiles succesfully! So is f(arr, 1, 2.0)
. So it seems N
can be deduced, at least in g++ and clang++.– CygnusX1
Dec 15 at 8:32
Clang gives this notice "candidate template ignored: invalid explicitly-specified argument for template parameter 'Ts'". The invocation
f<int, double>(arr, 1, 2.0)
compiles succesfully! So is f(arr, 1, 2.0)
. So it seems N
can be deduced, at least in g++ and clang++.– CygnusX1
Dec 15 at 8:32
@CygnusX1....sorry my bad...i have edited the question....it is actually N+1 and not N....
– Ashish Daggubatti
Dec 15 at 8:39
@CygnusX1....sorry my bad...i have edited the question....it is actually N+1 and not N....
– Ashish Daggubatti
Dec 15 at 8:39
add a comment |
1 Answer
1
active
oldest
votes
The fact that N cannot be deduced has nothing to do with the parameter pack. This doesn't compile either because N cannot be deduced.
template<int N>
void f(double (&)[N+1]) {}
int main() {
double arr[2];
f(arr);
}
From cppreference (Non-deduced contexts):
In the following cases, the types, templates, and non-type values that are used to compose P do not participate in template argument deduction, but instead use the template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
[...]
3) A non-type template argument or an array bound in which a subexpression references a template parameter
The fact that N cannot be specified has a different cause: the standard says that you simply cannot specify a parameter placed after a parameter pack.
From [temp.param]:
A template parameter pack of a function template shall not be followed
by another template parameter unless that template parameter can be deduced from the parameter-type-list
of the function template or has a default argument (14.8.2). [Example:
template<class T1 = int, class T2> class B; // error
// U can be neither deduced from the parameter-type-list nor specified
template<class... T, class... U> void f() { } // error
template<class... T, class U> void g() { } // error
—end example ]
(see this question from which I got the quote)
Your other example works because T
can be deduced from the parameters.
template<typename... Ts, typename T>
void func(T value){};
func(1); // 1 is used to deduce T
Thank you so much Nelfeal. That answers the question perfectly.
– Ashish Daggubatti
Dec 15 at 9:25
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%2f53790563%2fnon-deduced-context-for-a-non-type-parameter%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The fact that N cannot be deduced has nothing to do with the parameter pack. This doesn't compile either because N cannot be deduced.
template<int N>
void f(double (&)[N+1]) {}
int main() {
double arr[2];
f(arr);
}
From cppreference (Non-deduced contexts):
In the following cases, the types, templates, and non-type values that are used to compose P do not participate in template argument deduction, but instead use the template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
[...]
3) A non-type template argument or an array bound in which a subexpression references a template parameter
The fact that N cannot be specified has a different cause: the standard says that you simply cannot specify a parameter placed after a parameter pack.
From [temp.param]:
A template parameter pack of a function template shall not be followed
by another template parameter unless that template parameter can be deduced from the parameter-type-list
of the function template or has a default argument (14.8.2). [Example:
template<class T1 = int, class T2> class B; // error
// U can be neither deduced from the parameter-type-list nor specified
template<class... T, class... U> void f() { } // error
template<class... T, class U> void g() { } // error
—end example ]
(see this question from which I got the quote)
Your other example works because T
can be deduced from the parameters.
template<typename... Ts, typename T>
void func(T value){};
func(1); // 1 is used to deduce T
Thank you so much Nelfeal. That answers the question perfectly.
– Ashish Daggubatti
Dec 15 at 9:25
add a comment |
The fact that N cannot be deduced has nothing to do with the parameter pack. This doesn't compile either because N cannot be deduced.
template<int N>
void f(double (&)[N+1]) {}
int main() {
double arr[2];
f(arr);
}
From cppreference (Non-deduced contexts):
In the following cases, the types, templates, and non-type values that are used to compose P do not participate in template argument deduction, but instead use the template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
[...]
3) A non-type template argument or an array bound in which a subexpression references a template parameter
The fact that N cannot be specified has a different cause: the standard says that you simply cannot specify a parameter placed after a parameter pack.
From [temp.param]:
A template parameter pack of a function template shall not be followed
by another template parameter unless that template parameter can be deduced from the parameter-type-list
of the function template or has a default argument (14.8.2). [Example:
template<class T1 = int, class T2> class B; // error
// U can be neither deduced from the parameter-type-list nor specified
template<class... T, class... U> void f() { } // error
template<class... T, class U> void g() { } // error
—end example ]
(see this question from which I got the quote)
Your other example works because T
can be deduced from the parameters.
template<typename... Ts, typename T>
void func(T value){};
func(1); // 1 is used to deduce T
Thank you so much Nelfeal. That answers the question perfectly.
– Ashish Daggubatti
Dec 15 at 9:25
add a comment |
The fact that N cannot be deduced has nothing to do with the parameter pack. This doesn't compile either because N cannot be deduced.
template<int N>
void f(double (&)[N+1]) {}
int main() {
double arr[2];
f(arr);
}
From cppreference (Non-deduced contexts):
In the following cases, the types, templates, and non-type values that are used to compose P do not participate in template argument deduction, but instead use the template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
[...]
3) A non-type template argument or an array bound in which a subexpression references a template parameter
The fact that N cannot be specified has a different cause: the standard says that you simply cannot specify a parameter placed after a parameter pack.
From [temp.param]:
A template parameter pack of a function template shall not be followed
by another template parameter unless that template parameter can be deduced from the parameter-type-list
of the function template or has a default argument (14.8.2). [Example:
template<class T1 = int, class T2> class B; // error
// U can be neither deduced from the parameter-type-list nor specified
template<class... T, class... U> void f() { } // error
template<class... T, class U> void g() { } // error
—end example ]
(see this question from which I got the quote)
Your other example works because T
can be deduced from the parameters.
template<typename... Ts, typename T>
void func(T value){};
func(1); // 1 is used to deduce T
The fact that N cannot be deduced has nothing to do with the parameter pack. This doesn't compile either because N cannot be deduced.
template<int N>
void f(double (&)[N+1]) {}
int main() {
double arr[2];
f(arr);
}
From cppreference (Non-deduced contexts):
In the following cases, the types, templates, and non-type values that are used to compose P do not participate in template argument deduction, but instead use the template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
[...]
3) A non-type template argument or an array bound in which a subexpression references a template parameter
The fact that N cannot be specified has a different cause: the standard says that you simply cannot specify a parameter placed after a parameter pack.
From [temp.param]:
A template parameter pack of a function template shall not be followed
by another template parameter unless that template parameter can be deduced from the parameter-type-list
of the function template or has a default argument (14.8.2). [Example:
template<class T1 = int, class T2> class B; // error
// U can be neither deduced from the parameter-type-list nor specified
template<class... T, class... U> void f() { } // error
template<class... T, class U> void g() { } // error
—end example ]
(see this question from which I got the quote)
Your other example works because T
can be deduced from the parameters.
template<typename... Ts, typename T>
void func(T value){};
func(1); // 1 is used to deduce T
edited Dec 15 at 9:02
answered Dec 15 at 8:55
Nelfeal
4,894724
4,894724
Thank you so much Nelfeal. That answers the question perfectly.
– Ashish Daggubatti
Dec 15 at 9:25
add a comment |
Thank you so much Nelfeal. That answers the question perfectly.
– Ashish Daggubatti
Dec 15 at 9:25
Thank you so much Nelfeal. That answers the question perfectly.
– Ashish Daggubatti
Dec 15 at 9:25
Thank you so much Nelfeal. That answers the question perfectly.
– Ashish Daggubatti
Dec 15 at 9:25
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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%2f53790563%2fnon-deduced-context-for-a-non-type-parameter%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
@πάντα ῥεῖ - Hmmm...This compiles fine - template<typename... Ts, typename T> void func(T value){}; func(1); even though I have an additional parameter after a parameter pack. Once again, my question here is different from the one you have linked to as I am not asking the compiler to do the deduction but I am helping it with the deduction. Need to understand why that fails.
– Ashish Daggubatti
Dec 15 at 8:30
Clang gives this notice "candidate template ignored: invalid explicitly-specified argument for template parameter 'Ts'". The invocation
f<int, double>(arr, 1, 2.0)
compiles succesfully! So isf(arr, 1, 2.0)
. So it seemsN
can be deduced, at least in g++ and clang++.– CygnusX1
Dec 15 at 8:32
@CygnusX1....sorry my bad...i have edited the question....it is actually N+1 and not N....
– Ashish Daggubatti
Dec 15 at 8:39