2015-08-22 3 views
-2

Мы все знаем, что такое шаблон. По сути, это часть кода, которая проверяется на наличие ошибок только тогда, когда использовалась ее копия и все аргументы, которые были установлены.Часть кода в качестве аргумента шаблона

Мы также знаем, что аргументы шаблона должны быть выражениями с постоянным значением. Поэтому мы не можем использовать переменные в качестве аргументов для шаблона.

Но мы видим, что когда шаблон скомпилирован, код, ответственный за него, подобен скопированному с аргументами, вставленными на формальные параметры.

Можем ли мы использовать часть кода в качестве аргумента шаблона?

Например, мы имеем:

template<bool arg> 
class foo 
{ 
bool val; 
public: 
foo() : val(arg) {}; 
} 

Everething нормально, то будет хорошо работает, как arg является постоянной величиной. Но я want't использовать статическую часть кода, вставленную в шаблон, как это:

class foo 
{ 
    int a,b,c; 
public: 
    foo() : a(0),b(0),c(0) 
    {}; 
    foo(int an, int bn, int cn) : a(an),b(bn),c(cn) 
    {}; 
    template<partOfCode cond> 
    bool foo_check() 
    { 
     if(cond) return true; 
     else return false; 
    }; 
}; 

int main(char* args, char** argv) 
{ 
    foo foovar; 
    foovar.foo_check<this->a==0>(); 
    //or 
    foovar.foo_check<a==3>(); 
}; 

Конечно, я получаю ошибки, пытаясь сделать так. Но если на самом деле вставить часть кода аргумента в шаблон на своем месте, по крайней мере не будет никаких синтаксических ошибок.

Кто-то может ответить, что я могу использовать директиву define. Но это не поможет, поскольку шаблон и препроцессор независимы.

Есть ли способ реализовать что-то подобное?

+0

Вы пытаетесь * путь * слишком сильно. Такие вещи, как 'if (cond), возвращают true; else return false; 'также может быть записано как' return cond; 'и не нуждается в функции. –

+0

Компилятор также подумает, что 'foo_check ' является полным расширением шаблона, а затем задается вопросом, что делает остальная часть строки. –

ответ

2

Шаблоны не копировать текст, как макросы делают, так что вы:

  1. пытается ссылаться this в функции, не являющихся членами
  2. пытается получить доступ к переменной недоступных
  3. пытается создать экземпляр шаблона с время выполнения значение вместо компиляции постоянной

Вы должны передать функцию:

template <typename FunctionToCall> 
bool foo_check(FunctionToCall func) 
{ 
    return func(); // simplified 
}; 

// this is how you call it with lambda function 
foovar.foo_check([&]{ return foovar.get_a() == 0; }); // still have to provide an accessor, or make a friend function instead 

Черта с шаблоном, если вам нужно просто работать на условиях, вы можете сделать

bool foo_check(std::function<bool()> const& func) 
{ 
    return func(); // at this point, isn't foo_check useless? 
} 
Смежные вопросы