Подтвердить что ты не робот

Какой лучший способ вернуть кортеж из функции в С++ 11?

Я хочу вернуть некоторые значения из функции, и я хочу упаковать ее в кортеж. Поэтому у меня есть две возможности для объявления функции:

std::tuple<bool, string, int> f()
{
  ...
  return std::make_tuple(false, "home", 0);
}

и

std::tuple<bool, string, int> f()
{
  ...
  return std::forward_as_tuple(false, "home", 0);
}

Эти функции эквивалентны? Между этими функциями, которые вы предпочитаете?

4b9b3361

Ответ 1

std::forward_as_tuple() создает кортеж ссылок. Так как вы все равно возвращаете tuple<bool, string, int>, в этом случае они становятся эквивалентными, но я думаю, что первый подход более понятен - использование forward_as_tuple(), когда вы не пересылаете что-либо, путается.

Кроме того, как упоминалось в комментариях Себастьяном Редлом, make_tuple() разрешает компилятору выполнять копирование в соответствии с параграфом 12.8/31 стандарта С++ 11, тогда как forward_tuple() не будет (поскольку то, что оно возвращает не имеет того же типа, что и тип возвращаемой функции).

Ответ 2

Я предпочитаю,

std::tuple<bool, std::string, int> f()
{
  ...
  return { false, "home", 0 };
}

EDIT 1

Вышеприведенный код фактически компилируется для меня под связью clang/libС++. Поскольку @AndyProwl прокомментировал раздел комментариев, это не следует, поскольку конструктор std:: tuple является явным, а возврат через синтаксис списка инициализации - в контексте инициализации копии, а следовательно, и в инициализации списка копий, который не выполняется, когда явный конструктор сопоставляется.

Я не знаю, почему происходит clang/libС++, я полагаю, что это ошибка в libС++. Во всяком случае, это грустно, что нельзя делать это для кортежей...

Думаю, я понял, как грустно (для меня, наконец) это вообще. Я привык к этому синтаксису, но нужно заранее знать, будет ли возвращаемый тип содержать явный конструктор в любое время для его работы.

EDIT 2

Это действительно расширение libС++, для получения дополнительной информации, проверка Howard Hinnant здесь: fooobar.com/info/237312/....

В настоящее время он также открыт в списке ошибок libС++: http://llvm.org/bugs/show_bug.cgi?id=15299.

Это соответствующее предложение: Даниэль Крюглер, Улучшение пары и кортежа.

Короче говоря, это происходит с libС++:

#include <tuple>
#include <string>

struct S
{
    explicit S(int) {}
};

int main()
{
    std::tuple<int, std::string> t1 = { 1, "hello" }; // ok
    std::tuple<std::string> t2      = "hello";        // ok
    std::tuple<int, S> t3           = { 1, 1 };       // fail: an *element* is to be constructed explicitly
}