1

Это действительно основной вопрос, который я думаю, но я не смог найти ответ даже на StackOverflow. Извините, если вы хотите ударить меня, когда вы это прочитаете.Шаблон частичной специализации на bool

Я просто хочу сделать частичную специализацию на логическое значение:

template < typename Object, bool Shared = false > 
class Foo { 

    void bar(); 
}; 

template < typename Object > 
void Foo<Object, true>::bar() {} 

template < typename Object > 
void Foo<Object, false>::bar() {} 

int main() { 

    Foo<int> test; 
    return 0; 
} 

Я думаю, что идея правильная, но я что-то отсутствует с этим кодом (вероятно, действительно глупый):

Test3.cpp:8:30: error: invalid use of incomplete type ‘class Foo<Object, true>’ 
void Foo<Object, true>::bar() { 
          ^
Test3.cpp:2:7: note: declaration of ‘class Foo<Object, true>’ 
class Foo { 
     ^~~ 
Test3.cpp:13:31: error: invalid use of incomplete type ‘class Foo<Object, false>’ 
void Foo<Object, false>::bar() { 
          ^
Test3.cpp:2:7: note: declaration of ‘class Foo<Object, false>’ 
class Foo { 
+0

Вы не должны пытаться специализироваться класс? Похоже, вы пытаетесь определить функцию, которая является частью специализации. –

+0

Вы не можете частично специализировать функцию/метод, но можете полностью ее выделить: 'template <> void Foo :: bar() {}' [Demo] (http://coliru.stacked-crooked.com/a/18f9ddb32cf72ddd) – Jarod42

ответ

1

Ваш шаблон определяет класс, а не функцию. Это означает, что вы должны специализироваться этого класса, а не метод класса:

template < typename Object > 
class Foo<Object, false> { 
    void bar(); 
}; 

template < typename Object > 
class Foo<Object, true> { 
    void bar(); 
}; 
+0

Спасибо, мне нужно немного отдохнуть. –

+0

Нет проблем. Никогда не следует кодировать C++, не получая полный ночной сон и сытный завтрак. Вам следовало бы научить этому в Computer Science 101. –

+0

@SamVarshavchik Ну, я думаю, что стоит упомянуть здесь, что нельзя делать ** частичную ** специализацию класса по объявлению метода, а явную специализацию, например [this] (http : //melpon.org/wandbox/permlink/i0dGa1WaBgEq3jcn) будет абсолютно корректным. –

1

Другой способ заключается в разлагать Foo и обработать реализацию бар в отдельном вспомогательном классе. Это уменьшает количество повторений, необходимых для реализации Foo.

Например:

template<class Object, bool Shared> 
struct implement_bar; 

template<class Object> 
struct implement_bar<Object, true> 
{ 
    void operator()(Object& o) const 
    { 
    // do true thing with o 
    } 
}; 

template<class Object> 
struct implement_bar<Object, false> 
{ 
    void operator()(Object& o) const 
    { 
    // do false thing with o 
    } 
}; 

template < typename Object, bool Shared = false > 
class Foo { 

    void bar() 
    { 
    return implement_bar<Object, Shared>()(*this); 
    } 
}; 

int main() { 

    Foo<int> test; 
    return 0; 
} 
+0

Какой из них должен быть лучше: split или std :: enable_if? –

+0

@MathieuVanNevel, который проще всего читать, понимать и поддерживать. –