Программа A создает ошибку компиляции (как ожидалось), так как isFinite
вызывается с нецелым типом.
Программа A
#include <iostream>
class Foo {};
template<typename T>
bool isFinite(const T& t)
{
static_assert(std::is_integral<T>::value, "Called isFinite with a non-integral type");
return false;
}
int main()
{
Foo f;
std::cout << "Foo is finite? " << ((isFinite(f)) ? "yes" : "no") << "\n";
return 0;
}
Однако небольшая модификация (см. Программа B) позволяет программе скомпилировать (Visual Studio 2013) и произвести следующий вывод.
Программа B Visual Studio 2013 Ouput
Foo is finite? yes
Программа B
#include <iostream>
class Foo {};
template<typename T>
bool isFinite(const T& t)
{
static_assert(std::is_integral<T>::value, "Called isFinite with a non-integral type");
return false;
}
int main()
{
Foo f;
std::cout << "Foo is finite? " << ((true || isFinite(f)) ? "yes" : "no") << "\n";
return 0;
}
Похоже, что Программа B коротко замыкается на логическую операцию ИЛИ и не пытается скомпилировать остальную часть выражения. Однако, это приложение не компилируется с помощью g++ 4.8.3 (g++ -std=c++11 -o main main.cpp
). Я получаю следующий вывод.
main.cpp: In instantiation of 'bool isFinite(const T&) [with T = Foo]':
main.cpp:15:56: required from here
main.cpp:8:2: error: static assertion failed: Called isFinite with a non-integral type
static_assert(std::is_integral<T>::value, "Called isFinite with a non-integral type");
^
Моя интуиция заставляет меня думать, что сбой компиляции - это правильное поведение , но любопытно, что Visual Studio 2013 успешно компилируется. Моя интуиция основана на том факте, что ожидается, что следующий код не может быть скомпилирован.
#include <iostream>
struct Foo
{
void doOperation1() {}
void doOperation2() {}
};
struct Bar
{
void doOperationA() {}
void doOperation2() {}
};
template<typename T>
void performOperation(T& t, bool value)
{
if (value)
{
t.doOperation1();
}
else
{
t.doOperation2();
}
}
int main()
{
Foo f;
performOperation(f, true);
performOperation(f, false);
Bar b;
performOperation(b, false); // Fails to compile (as expected)
return 0;
}
Повторный вопрос
Предполагаются ли логические операторы придерживаться правил оценки коротких замыканий во время компиляции (т.е. каково ожидаемое поведение компиляции Программы B)?