Злоупотребление оператором запятой

Лучший пример, который я имею, столкнулся (и читайте во многих книгах), тот, который использует Форму.

лучшая вещь об этом состоит в том, что можно очень легко объяснить все понятия (включая жесткие) связанный с ООП как Класс, Объект, Наследование, Абстракция, Инкапсуляция, Полиморфизм, и т.д. любому программисту, не важному из его опыта.

9
задан miked 27 January 2016 в 22:03
поделиться

7 ответов

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

например, так же, как вы можете написать:

int a=3, b=4

Мне кажется, что вы, по сути, пишете:

Strings s="Hello", stringliteral

Итак, компилятор ожидает, что элемент после запятой будет именем переменной, и вместо этого он видит строковый литерал и сообщает об ошибке. Другими словами, конструктор применяется к «Hello», но запятая после него не оператор запятой для строк.

Между прочим, конструктор на самом деле не является конструктором копирования. Он создает объект Strings из литерального строкового параметра ... Конструктор копирования термина обычно применяется к тому же типу.

14
ответ дан 4 December 2019 в 07:47
поделиться

Вы можете использовать массив символьных указателей

Strings::Strings(const char* input[]);

const char* input[] = {
  "string one",
  "string two",
  0};

Strings s(input);

а внутри конструктора перебирайте указатели, пока не достигнете нуля.

0
ответ дан 4 December 2019 в 07:47
поделиться

Я бы не рекомендовал такой API. Вы продолжите обнаруживать случаи, которые не работают должным образом, поскольку запятая - это оператор с самым низким приоритетом. Например, этот случай тоже не будет работать:

if ("Hello","world" == otherStrings) { ... }

Вы можете заставить все работать, если будете каждый раз использовать скобки вокруг набора строк, например:

Strings s=("Hello","World!");

И мой пример выше будет выглядеть так:

if (("Hello","world") == otherStrings) { ... }

Это, вероятно, можно заставить работать, но сокращенный синтаксис, вероятно, не стоит той сложной семантики, которая с ним связана.

8
ответ дан 4 December 2019 в 07:47
поделиться

Это возможно сделать, если определение термина «работа» достаточно вольное. Вот рабочий пример, который я написал в ответ на аналогичный вопрос несколько лет назад. Это была забавная задача, но я бы не стал использовать ее в реальном коде:

#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>

void f0(std::vector<int> const &v) { 
    std::copy(v.begin(), v.end(), 
        std::ostream_iterator<int>(std::cout, "\t"));
    std::cout << "\n";
}

template<class T>
class make_vector {
    std::vector<T> data;
public:
    make_vector(T const &val) { 
        data.push_back(val);
    }

    make_vector<T> &operator,(T const &t) {
        data.push_back(t);
        return *this;
    }

    operator std::vector<T>() { return data; }
};

template<class T> 
make_vector<T> makeVect(T const &t) { 
    return make_vector<T>(t);
}

int main() { 
    f0((makeVect(1), 2, 3, 4, 5));
    f0((makeVect(1), 2, 3));
    return 0;
}
1
ответ дан 4 December 2019 в 07:47
поделиться

Используйте boost :: list_of .

5
ответ дан 4 December 2019 в 07:47
поделиться

Если вы используете c ++ 0x, у них есть новые списки инициализаторов для этого! Я бы хотел, чтобы вы могли их использовать. Например:

std::vector<std::string> v = { "xyzzy", "plugh", "abracadabra" };
std::vector<std::string> v{ "xyzzy", "plugh", "abracadabra" };
0
ответ дан 4 December 2019 в 07:47
поделиться

Если единственная задача Strings - хранить список строк, тогда boost :: assign мог бы лучше справиться со стандартными контейнерами, я думаю: )

using namespace boost::assign;
vector<string> listOfThings;
listOfThings += "Hello", "World!";
0
ответ дан 4 December 2019 в 07:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: