Почему C ++ не находит оператор bool, когда есть!оператор по объему? - PullRequest
0 голосов
/ 17 мая 2018

Работа над библиотекой комбинатора синтаксического анализатора, из которой получен этот пример, хотя очевидно, что некоторые имена были изменены для защиты невинных:

#include <string>
#include <stdio.h>

using namespace std;

template <typename T> struct only_string;
template <>           struct only_string<string> {};

struct another_type {
    explicit operator bool() const { return true; }
};


// only substitute if T is string
template <typename T>
bool operator !(T) {
    only_string<T> a;
    return true;
}


int main() {
    another_type a;
    if (!a) {
        return 1;
    } else {
        return 0;
    }    
}

У меня есть оператор шаблона! он должен подставляться только тогда, когда T является строкой, а другой тип имеет оператор bool. Если я пытаюсь вызвать! A, он сначала находит оператора, не может заменить и сдается. Кто-нибудь может объяснить это поведение и как исправить его?

Это вывод с g ++ 5.4.0

> g++ -std=c++11 test.cc -o test

test.cc: In instantiation of ‘bool operator!(T) [with T = another_type]’:
test.cc:24:10:   required from here
test.cc:17:20: error: ‘only_string<another_type> a’ has incomplete type
     only_string<T> a;
                    ^

1 Ответ

0 голосов
/ 17 мая 2018

Да, компилятор "сдался", потому что он думал, что! Оператор был лучшим матчем. Если вы действительно хотите, чтобы компилятор игнорировал эту перегрузку, вам нужно использовать технику, называемую SFINAE.

template <typename T,
        std::enable_if_t<std::is_same_v<T, std::string>>* = nullptr>
bool operator !(T) {
    return true;
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...