инициализация элемента эталонного класса gtest fixture с временным - PullRequest
0 голосов
/ 16 сентября 2018

Просто изучаю гтест и сталкиваюсь с чем-то, касающимся времени жизни объекта, которого я не получаю. Учитывая это тестовое приспособление, инициализирующее ссылку на член класса с временным:

#include "gtest/gtest.h"

struct Base {

  bool check() const {
    if (str_ == "test") return true;
    return false;
  }

  private:
    std::string str_{"test"}; 
};  

struct Foo : public Base {};

class FooTest : public ::testing::Test {
protected:
  FooTest() : b{Foo{}} {}
  const Base& b;
};

TEST_F(FooTest, RefOne) {
  const Base& x{Foo{}};
  ASSERT_TRUE(x.check());
}

TEST_F(FooTest, RefTwo) {
  ASSERT_TRUE(b.check());
}

первый тест пройден, а второй тест не пройден с неинициализированной ссылкой.

Но если я тестирую точно такой же код Base и Foo со своим собственным классом тестирования и получаю доступ к методу check () через main:

// same Base and Foo code

struct Tester { 
  Tester() : b{Foo{}}

  const Base& get() const {
    return b;
  }

private:
  const Base& b;
};

int main() {
  Tester t;
  if (t.get().check()) std::cout << "Pass." << std::endl;
}

ссылка действительна. Единственный способ передать версию gtest - это инициализация ссылки lvalue.

Я использую gtest 1.8.0 и собираю с g ++ -std = c ++ 17 -g -Wall -O3.

Из cppreference: временная привязка к элементу ссылки в списке инициализатора конструктора сохраняется только до выхода из конструктора, а не до тех пор, пока существует объект. (примечание: такая инициализация некорректна по состоянию на DR 1696). (до C ++ 14)

Это несовпадение версии gtest / c ++? Я на правильном пути, чтобы понять это?

1 Ответ

0 голосов
/ 16 сентября 2018

Упомянутая вами часть cppreference «до C ++ 14» не означает, что начиная с C ++ 17 и далее время существования временного объекта больше не заканчивается при выходе из конструктора, совсем наоборот [class.base.init / 8] теперь утверждает, что

Временное выражение, привязанное к ссылочному элементу в mem-initializer, неверно сформировано.

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

...