Есть ли способ частичного экземпляра шаблона C ++ - PullRequest
0 голосов
/ 21 декабря 2018

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

struct T1
{
    int getData(){return 1;}
};

struct T2
{
    string getData(){return "string";}
};

struct T3
{
    // no getData()
};

template<typename T>
void printData(T param)
{
    cout << param.getData() << endl;
}

int main() {

    T1 t1;
    T2 t2;
    T3 t3;

    printData(t1);
    printData(t2);
    printData(t3);  // fails for T3 has no getData
}

Я хочу знать, есть ли какой-то способвот так (псевдокод):

template<typename T>
void printData(T param)
{
    if(T != T3) // compile time check, instance on this condition
    {
        cout << param.getData() << endl;
    }
}

Я пробовал std::is_same, но это не сработало

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

Начиная с C ++ 17, вы можете использовать if constexpr (!std::is_same_v<T, T3>), как предлагается в ответе сонгюаняо.

В C ++ 11 / C ++ 14 я предлагаю два способа.

(1) отправка меток

template <typename T>
void printData (T param, std::true_type)
 { }

template <typename T>
void printData (T param, std::false_type)
 { std::cout << param.getData() << std::endl; }

template <typename T>
void printData (T param)
 { printData(param, std::is_same<T, T3>{}); }

(2) SFINAE

// ever enabled
template <typename T>
void printData (T param, long)
 { }

// preferred (int instead of long) but enabled only
// when param support getData()
template <typename T>
auto printData (T param, int)
   -> decltype( param.getData(), void() )
 { std::cout << param.getData() << std::endl; }

template <typename T>
void printData (T param)
 { printData(param, 0); }
0 голосов
/ 21 декабря 2018

Проблема в том, что Statement_true все равно будет оцениваться при компиляции, когда T равно T3, что приводит к ошибке компиляции.

Вы можете использовать Constexpr If (так как C++ 17).

Если значение равно true, то ложное утверждение отбрасывается (если присутствует), в противном случае истинное утверждение отбрасывается.

например,

if constexpr (!std::is_same_v<T, T3>)
{
    cout << param.getData() << endl;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...