Różne zachowania klasy na podstawie przekazanego parametru lub jego braku

0

Hej,

Chcę by klasa Object miała różną deklarację na podstawie warunku dostarczenia parametru szablonu lub jego braku.
Poniższy kod działa na VS2019 ale już w G++ 10.1.0 nie:

enum class Values
{
 A,
 B
};

template<Values...values>
class Object;

template<>
class Object<>
{
public:
   void t()
   {

   }
};

template<Values value>
class Object<value>
{
   void g()
   {

   }
};

Co robię źle?

Komunikat błędu:

  1. too many template-parameter-lists
  2. template parameters not deducible in partial specialization
0
#include <iostream>
using namespace std;

enum class Values:uint8_t { A=0x41, B=0x42 };

template<typename Values> class Object
{
	public:
	void foo() { cout<<"empty"; }
	void foo(Values v) { cout<<(char)v<<' '; }
	template<typename... Args> void foo(Values v,Args... args)
	{
		foo(v);
	    foo(args...);
	}
	void foo(initializer_list<Values> list) { for(Values v:list) foo(v); }
};

int main()
{
	Object<Values> obj;
	obj.foo(); cout<<endl;
	obj.foo(Values::A); cout<<endl;
	obj.foo(Values::A,Values::B); cout<<endl;
	obj.foo({Values::A}); cout<<endl;
	obj.foo({Values::A,Values::B});
	return 0;
}
1

Na pewno chodzi o deklarację? Co chcesz osiągnąć, ale innymi słowami, bo zupełnie nie rozumiem. Chodzi o specjalizację szablonów?

0

Porobiłem jeszcze kilkanaście testów i troszkę się pogubiłem.
Przykładowy kod działa prawidłowo i na MSVC i na G++.
Problem dopiero pojawia się, gdy damy ten frgament wenwatrz deklaracji innej klasy:

    class Aaaaa
    {
    public:
        template<int ...value>
        class Qewqwerw;

        template<>
        class Qewqwerw<>
        {
        public:
            void test()
            {
                std::cout << "Q::test(without param)" << std::endl;
            }
        };

        template<int value>
        class Qewqwerw<value>
        {
        public:
            void test()
            {
                std::cout << "Q::test(" << value << ")" << std::endl;
            }
        };
    };

int main()
{
Aaaaa::Qewqwerw<>{}.test();
        Aaaaa::Qewqwerw<1>{}.test();
        Aaaaa::Qewqwerw<2>{}.test();
return 0;
}
0

Oooo ale to działa:

    class Aaaaa
    {
    public:
        template<int ...value>
        class Qewqwerw
        {
        public:
            void test()
            {
                std::cout << "Q::test(without param)" << std::endl;
            }
        };

        template<int value>
        class Qewqwerw<value>
        {
        public:
            void test()
            {
                std::cout << "Q::test(" << value << ")" << std::endl;
            }
        };
    };

Tylko dlaczego...?

2

Twoje pytanie się kompiluje bez kłopotu: https://godbolt.org/z/e5zr38nPr jedyny problem to, Object<Values::A, Values::B> c; bo nie ma domyślnej implementacji szablonu.

Nie sprawdzałem późniejszy postów, ale fajnie byłoby jakbyś dostarczył Minimalny Kompletny Reprodukowany Przykład, najlepiej używając do tego jakiegoś kopilatora online, jak https://godbolt.org lub http://wandbox.org/ lub http://coliru.stacked-crooked.com/ lub ....

2

Post, który ma nie działać (sformatowany), ma problemy tylko na gcc: https://godbolt.org/z/WohM6bPcY

Jednak błąd sugeruje co zrobić:

<source>:8:15: error: explicit specialization in non-namespace scope 'class Aaaaa'
    8 |     template <>
      |               ^
<source>:18:11: error: too many template-parameter-lists
   18 |     class Qewqwerw<value> {
      |           ^~~~~~~~~~~~~~~

Wersja naprawiona:

#include <iostream>

class Aaaaa {
public:
    template <int... value>
    class Qewqwerw;
};

template <>
class Aaaaa::Qewqwerw<> {
public:
    void test()
    {
        std::cout << "Q::test(without param)" << std::endl;
    }
};

template <int value>
class Aaaaa::Qewqwerw<value> {
public:
    void test()
    {
        std::cout << "Q::test(" << value << ")" << std::endl;
    }
};

int main()
{
    Aaaaa::Qewqwerw<>{}.test();
    Aaaaa::Qewqwerw<1>{}.test();
    Aaaaa::Qewqwerw<2>{}.test();
    return 0;
}

https://godbolt.org/z/YasjbMYb4

Nauka jest prosta, zawsze czytaj/kopiuj logi błędów zaczynając zaczynając od pierwszego wpisu!

1 użytkowników online, w tym zalogowanych: 0, gości: 1