При работе с макросами конечный инструмент анализирует расширенный макрос:
В вашем случае (и для gtest 1.6):
EXPECT_THROW(MyClass(filename), std::runtime_error);
Расширяется до:
...
bool gtest_caught_expected = false; \
try { \
if (::testing::internal::AlwaysTrue()) { MyClass(filename); }; \
} \
catch (std::runtime_error const&) { \
gtest_caught_expected = true; \
} \
catch (...) { \
gtest_msg.value = \
"Expected: " "MyClass(filename)" " throws an exception of type " \
"std::runtime_error" ".\n Actual: it throws a different type."; \
goto gtest_label_testthrow_88; \
} \
if (!gtest_caught_expected) { \
gtest_msg.value = \
"Expected: " "MyClass(filename)" " throws an exception of type " \
"std::runtime_error" ".\n Actual: it throws nothing."; \
goto gtest_label_testthrow_88; \
} \
...
Как видите, аргумент EXPECT_THROW
- это не объект, а выражение, которое будет оцениваться в дальнейшем, в рамках GTEST предусмотрен допустимый блок try / catch.
Поэтому все, что вы передаете ему, должно быть в состоянии оценитькак выражение в пределах вложенной области текущей области.В вашем случае:
MyClass(filename)
является неоднозначным, но в соответствии с наиболее досадным правилом синтаксического анализа, интерпретация объявления предпочтительнее, поэтому вы получите:
MyClass filename
Итак, вы создаете переменную с именемимя файла класса MyClass - и, следовательно, ошибка об отсутствующем конструкторе.
Этот механизм не сработает, если вы используете литеральную строку:
MyClass("some string")
, потому что следующее будет недопустимым (и нет двусмысленности):
MyClass "some string"