2015-11-29 2 views
1

Я хотел бы работать с istringstream внутри функции, и я хочу, чтобы istringstream был инициализирован string, переданным по значению. Могу ли я избежать явного istringstream iss_input(string_input); в теле функции?Передача строки в аргумент istringsream функции

void f(istringstream command){ 
} 

int main(){ 
    f(string("create_customer 1 Ben Finegold")); 
} 

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

+1

Итак, вы хотите, чтобы параметр функции 'f (...)' использовался непосредственно для создания локального объекта 'istringstream' в функции' f'. Это то, что вы просите? – Lucien

+0

Я не понимаю, что вы получаете от этого и почему вы это сделаете. Если речь идет о рекурсивных вызовах, почему бы не перегрузить 'f'? –

+0

Конструктор 'istringstream' из' string' является явным, поэтому нет, вы не можете иметь неявное преобразование. Кроме того, 'istringstream' не копируется, вы не можете принять его по значению. Просто возьмите строку. –

ответ

0

Я не совсем уверен, что вы пытаетесь сделать с этим void f(...), но я думаю, что это должен делать то, что вы хотите:

template<typename... Args> 
void f(Args&&... args) 
{ 
    istringstream command(forward<Args>(args)...); 
    // You logics... 
} 

int main() 
{ 
    f("create_customer 1 Ben Finegold"s); 
    //... 
    return 0; 
} 

Edit 1

Я использую VARIADIC шаблон только в случае, если вы хотите инициализировать свой локальный поток другими потоками. Если строка вам нужно только инициализировать его со строками, вы можете сделать это:

void f(string&& str) 
{ 
    istringstream command(forward<Args>(str)); 
    // You logics... 
} 

, который, по существу, то же самое.

+1

Почему переменный шаблон, а не простой параметр 'std :: string' как параметр? – vsoftco

+0

@vsoftco На всякий случай Slazer нужно инициализировать поток другими вещами. – Lucien

+0

@Lucien Я не понимаю необходимости в вариационном шаблоне eitrher. Можете ли вы уточнить? – Slazer

1

В качестве параметра я бы просто использовал параметр std::string. Но если вы хотите передать std::istringstream, вам необходимо передать его явно f, так как std::istringstream конструктор, который принимает std::stringis marked explicit (#2). Пример:

f(std::istringstream{"create_customer 1 Ben Finegold"}); 

Код выше создает временную std::istringstream в качестве аргумента, который затем перемещается в параметр command вашей функции; он использует конструктор перемещения № 3 от here.

Обратите внимание, что нам не нужно неуклюжим

f(std::istringstream{std::string{"create_customer 1 Ben Finegold"}}); 

потому что const char* конструктор std::stringis not explicit (#5), и компилятор может выполнять не более одного неявного пользовательского преобразования. Поэтому в первой строке кода, которую я разместил, строковый литерал "create_customer 1 Ben Finegold" преобразуется в std::string, который затем используется для явного построения временного аргумента std::istringstream, который затем перемещается в command.

+0

Я думаю, вы забыли упомянуть, что мне нужно изменить команду 'istringstream'' 'istringstream && command' в' f() '. Однако моя идея состояла в том, чтобы передать 'string' в' f() ', let' f() 'создать' istringstream' прозрачно и сделать его доступным в теле ** без ** кода, создающего его в теле. Это возможно? – Slazer

+0

@Slazer Я не думаю, что вы хотите иметь аргумент 'istringstream &&', если только вы не хотите двигаться с места назначения и просто «проверяете» ссылку rvalue. В решении я разместил 'command' - это параметр, в который вы перемещаете' istringstream', который создается при вызове функции. В теле нет кода создания 'istringstream'. Я не думаю, что вы можете сделать это проще, потому что нет никакого неявного преобразования из 'string' в' istringstream'. – vsoftco

Смежные вопросы