Here's something I'm trying that doesn't seem to work: I want to toggle a compile time switch based on how a class object is instantiated. If there's just one constructor argument, the LengthOpt
should equal to false
, otherwise to true
(my implementation has more constructors where the switch should default to true
.
I tried to create a deduction guide, but apparently it doesn't work if the template argument doesn't show up as a constructor argument (which is a real downer). Does anyone know a not-too-verbose solution to this problem?
Code:
#include <cstring>
#include <iostream>
const char* str = "some input string";
template <bool LengthOpt>
class some_class
{
public:
some_class(const char*) {
std::cout << std::boolalpha << LengthOpt << std::endl;
}
some_class(const char*, size_t len) {
std::cout << std::boolalpha << LengthOpt << std::endl;
}
};
template <bool LengthOpt> some_class(const char*) -> some_class<false>;
template <bool LengthOpt> some_class(const char*, size_t) -> some_class<true>;
int main()
{
some_class A(str);
some_class B(str, strlen(str));
}
Errors:
<source>:19:27: error: deduction guide template contains a template parameter that cannot be deduced
template <bool LengthOpt> some_class(const char*) -> some_class<false>;
^
<source>:19:16: note: non-deducible template parameter 'LengthOpt'
template <bool LengthOpt> some_class(const char*) -> some_class<false>;
^
<source>:20:27: error: deduction guide template contains a template parameter that cannot be deduced
template <bool LengthOpt> some_class(const char*, size_t) -> some_class<true>;
^
<source>:20:16: note: non-deducible template parameter 'LengthOpt'
template <bool LengthOpt> some_class(const char*, size_t) -> some_class<true>;
^
<source>:24:16: error: no viable constructor or deduction guide for deduction of template arguments of 'some_class'
some_class A(str);
^
<source>:11:5: note: candidate template ignored: couldn't infer template argument 'LengthOpt'
some_class(const char*) {
^
<source>:19:27: note: candidate template ignored: couldn't infer template argument 'LengthOpt'
template <bool LengthOpt> some_class(const char*) -> some_class<false>;
^
<source>:8:7: note: candidate template ignored: could not match 'some_class<LengthOpt>' against 'const char *'
class some_class
^
<source>:14:5: note: candidate function template not viable: requires 2 arguments, but 1 was provided
some_class(const char*, size_t len) {
^
<source>:20:27: note: candidate function template not viable: requires 2 arguments, but 1 was provided
template <bool LengthOpt> some_class(const char*, size_t) -> some_class<true>;
^
<source>:25:16: error: no viable constructor or deduction guide for deduction of template arguments of 'some_class'
some_class B(str, strlen(str));
^
<source>:14:5: note: candidate template ignored: couldn't infer template argument 'LengthOpt'
some_class(const char*, size_t len) {
^
<source>:20:27: note: candidate template ignored: couldn't infer template argument 'LengthOpt'
template <bool LengthOpt> some_class(const char*, size_t) -> some_class<true>;
^
<source>:11:5: note: candidate function template not viable: requires 1 argument, but 2 were provided
some_class(const char*) {
^
<source>:8:7: note: candidate function template not viable: requires 1 argument, but 2 were provided
class some_class
^
<source>:19:27: note: candidate function template not viable: requires 1 argument, but 2 were provided
template <bool LengthOpt> some_class(const char*) -> some_class<false>;
^
4 errors generated.
ASM generation compiler returned: 1
<source>:19:27: error: deduction guide template contains a template parameter that cannot be deduced
template <bool LengthOpt> some_class(const char*) -> some_class<false>;
^
<source>:19:16: note: non-deducible template parameter 'LengthOpt'
template <bool LengthOpt> some_class(const char*) -> some_class<false>;
^
<source>:20:27: error: deduction guide template contains a template parameter that cannot be deduced
template <bool LengthOpt> some_class(const char*, size_t) -> some_class<true>;
^
<source>:20:16: note: non-deducible template parameter 'LengthOpt'
template <bool LengthOpt> some_class(const char*, size_t) -> some_class<true>;
^
<source>:24:16: error: no viable constructor or deduction guide for deduction of template arguments of 'some_class'
some_class A(str);
^
<source>:11:5: note: candidate template ignored: couldn't infer template argument 'LengthOpt'
some_class(const char*) {
^
<source>:19:27: note: candidate template ignored: couldn't infer template argument 'LengthOpt'
template <bool LengthOpt> some_class(const char*) -> some_class<false>;
^
<source>:8:7: note: candidate template ignored: could not match 'some_class<LengthOpt>' against 'const char *'
class some_class
^
<source>:14:5: note: candidate function template not viable: requires 2 arguments, but 1 was provided
some_class(const char*, size_t len) {
^
<source>:20:27: note: candidate function template not viable: requires 2 arguments, but 1 was provided
template <bool LengthOpt> some_class(const char*, size_t) -> some_class<true>;
^
<source>:25:16: error: no viable constructor or deduction guide for deduction of template arguments of 'some_class'
some_class B(str, strlen(str));
^
<source>:14:5: note: candidate template ignored: couldn't infer template argument 'LengthOpt'
some_class(const char*, size_t len) {
^
<source>:20:27: note: candidate template ignored: couldn't infer template argument 'LengthOpt'
template <bool LengthOpt> some_class(const char*, size_t) -> some_class<true>;
^
<source>:11:5: note: candidate function template not viable: requires 1 argument, but 2 were provided
some_class(const char*) {
^
<source>:8:7: note: candidate function template not viable: requires 1 argument, but 2 were provided
class some_class
^
<source>:19:27: note: candidate function template not viable: requires 1 argument, but 2 were provided
template <bool LengthOpt> some_class(const char*) -> some_class<false>;
^
4 errors generated.
Execution build compiler returned: 1
You don't need a template parameter, just do:
some_class(const char *) -> some_class<false>;
some_class(const char *, size_t) -> some_class<true>;
Deduction guides are like functions, but all their template parameters must be deducible from their function parameters.
template <bool LengthOpt> some_class(const char*) -> ...
turns into something like template <bool LengthOpt> void foo(const char*)
, where LengthOpt
is non-deducible.