In trying to understand c++17 compliant code, i am confused by the following code in which the function uses the value from integral_constant type argument in the trailing return type. (please feel free to correct my terminolgy etc, trying to learn)
Two simple versions are illustrated below , with and without a decltype on the argument in the trailing return.
Using Compiler Explorer https://godbolt.org/z/vqmzhu
The first (bool_from1) compiles ok on
MSVC 15.8; /std:c++17, /O2, /permissive-
and clang 8.7.0.0 and gcc 8.2; -std=c++17, -O2, -pedantic
with correct assembler output
The second (bool_from2) errors out on gcc, It also shows Intellisense errors in VS but compiles without error.
I could not find anything in cppreference or standard draft, etc that would indicate to me that the decltype(atype) would be required for conforming code, however...???
My question would be is the decltype required. Are my compiler flags correct for c++17 conformance checking.
CODE:
#include <utility>
namespace ns {
volatile bool vb;
template<bool B> struct bool_ : std::bool_constant<B> {};
// using decltype(btype) in trailing return compiles in all 3
template<typename Bool> constexpr auto bool_from1(Bool btype)
-> bool_<decltype(btype)::value> {
return bool_<btype.value>{};
}
void test1() {
static_assert( // simple test
bool_from1(std::true_type{}).value
);
vb = bool_from1(std::true_type{}).value; // check output
}
// without decltype in trailing return compile in VS and clang
// but errors out in gcc; and VS shows Intelisense errors but compiles
template<typename Bool>
constexpr auto bool_from2(Bool btype)
// ^ gcc 8.2 error: deduced class type 'bool_' in function return type
-> bool_<btype.value> {
// ^ gcc: invalid template-id; use of paramter outside function body before '.'
//^ VS Intellisense on btype: <error-constant>; a paramter is not allowed
return bool_<btype.value>{};
}
void test2() {
static_assert(
bool_from2(std::true_type{}).value
//^ gcc: bool_from1 was not declared in this scope
);
vb = bool_from2(std::true_type{}).value; // check output
}
}