Noexcept operatöründe std :: decay'e ihtiyaç var mı?
Sep 04 2020
Aşağıdaki kod , gcc'destd::decay inside kullanılmasını gerektirir ancak clang'da kullanılmaz .noexcept operator
template<typename... Ts>
class B;
template<typename T>
class B<T> {
T t;
public:
template<typename U>
constexpr B(U&& t)
// without decay - strange behavior in gcc, see main below <===
noexcept(noexcept(T{std::forward<U>(t)}))
// if adding decay - all cases in main are ok with both gcc and clang
// noexcept(noexcept(std::decay_t<T>{std::forward<U>(t)}))
: t(std::forward<U>(t)) {}
};
template<typename T, typename... Ts>
class B<T, Ts...>: protected B<Ts...> {
public:
template<typename U, typename... Us>
constexpr B(U&& t, Us&&... ts)
: B<Ts...>{std::forward<Us>(ts)...} {}
};
template<typename... Ts>
constexpr auto create(Ts&&... ts) {
return B<Ts...>{std::forward<Ts>(ts)...};
}
template<typename... Ts>
B(Ts...) -> B<Ts...>;
ana
int main() {
// ok in both gcc and clang:
// [1] the "hello" parameter is not last
auto b1 = create("hello", 1);
auto b2 = create(1, "hello", 5);
// [2] passing it directly to the ctor of B
B b3(1, "hello");
// fails with gcc when the noexcept doesn't use decay
// but only if "hello" is the last argument and passed via a function
auto b4 = create(1, "hello");
auto b5 = create("hello");
}
Gcc'nin derleme hatası şudur:
<source>:13:40: error: invalid conversion from 'const char*' to 'char'
[-fpermissive]
13 | noexcept(noexcept(T{std::forward<U>(t)}))
| ~~~~~~~~~~~~~~~^~~
| |
| const char*
Kod: https://godbolt.org/z/s7rf64
Bu garip davranış hakkında bir fikriniz var mı? Bu bir gcc hatası mı? veya std::decaygerçekten gerekli mi?
Yanıtlar
AmirKirsh Sep 04 2020 at 19:43
@Marek R tarafından yapılan açıklamanın ardından gcc'de bir hata var gibi görünüyor.
Gcc'de bir hata açıldı .
Aşağıdaki durum da gcc ile başarısız olur, clang ile değil:
template<typename T, typename U>
auto convert(U&& t) {
// fails on gcc:
return T{std::forward<U>(t)};
// works ok if it is not brace initialization:
// return T(std::forward<U>(t));
}
template<std::size_t INDEX, typename T, typename U, typename... Us>
auto convert(U&& t, Us&&... ts) {
if constexpr(INDEX == 0) {
return convert<U>(t);
// works well if we add decay
// return convert<std::decay_t<U>>(t);
}
else {
return convert<INDEX-1, T>(ts...);
}
}
int main() {
// fails with gcc
auto p = convert<1, const char*>(1, "hello");
}
Kod: https://godbolt.org/z/jqxbfj
Gene Simmons, KISS Çizgi Romanlarının Potansiyel Olarak "İnsanlığı Yeniden Yaratabileceğini" Söyledi
Donovan, Şarkılarından 1'ini The Beatles'ın "Lucy in the Sky with Diamonds" şarkısıyla karşılaştırdı
Tom Girardi Dolandırıcılık Suçlamalarından Yargılanma Yetkisinin Belirlenmesi İçin Duruşmaya Katıldı