Non Deduced context for a non type parameter












13














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.










share|improve this question
























  • @πάντα ῥεῖ - 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












  • @CygnusX1....sorry my bad...i have edited the question....it is actually N+1 and not N....
    – Ashish Daggubatti
    Dec 15 at 8:39
















13














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.










share|improve this question
























  • @πάντα ῥεῖ - 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












  • @CygnusX1....sorry my bad...i have edited the question....it is actually N+1 and not N....
    – Ashish Daggubatti
    Dec 15 at 8:39














13












13








13







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.










share|improve this question















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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


















  • @πάντα ῥεῖ - 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












  • @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












1 Answer
1






active

oldest

votes


















14














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





share|improve this answer























  • Thank you so much Nelfeal. That answers the question perfectly.
    – Ashish Daggubatti
    Dec 15 at 9:25











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
});


}
});














draft saved

draft discarded


















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









14














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





share|improve this answer























  • Thank you so much Nelfeal. That answers the question perfectly.
    – Ashish Daggubatti
    Dec 15 at 9:25
















14














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





share|improve this answer























  • Thank you so much Nelfeal. That answers the question perfectly.
    – Ashish Daggubatti
    Dec 15 at 9:25














14












14








14






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





share|improve this answer














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






share|improve this answer














share|improve this answer



share|improve this answer








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


















  • 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


















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

How do I know what Microsoft account the skydrive app is syncing to?

When does type information flow backwards in C++?

Grease: Live!