std :: is_constructible özel kurucu için tutarsız değer döndürüyor


13

std::is_constructibleÖzel kurucuları idare etme kuralları nelerdir ? Aşağıdaki kod verildiğinde:

#include <iostream>

class Class {
private:
    Class() { }
};

template <typename T>
class Test {
public:
    static void test() {
        std::cout
            //<< std::is_constructible<Class>::value
            << std::is_constructible<T>::value
            << std::endl;
    }
};

int main() {
    Test<Class>::test();
}

Bu baskı 0( ideone ), yani Tvarsayılan olarak yapılandırılamaz.

Yorumlanan satırın işareti kaldırıldığında , 11( ideone ) yazdırılır , böylece Taniden varsayılan olarak yapılandırılabilir hale gelir.

Her iki sonucu da desteklemek için mantık bulabilirim, ancak yorum yapılan satırı eklemenin ikincinin sonucunu nasıl değiştirdiğini anlamıyorum. Bu bir şekilde UB'yi mi çağırıyor? Bu bir derleyici hatası mı? Yoksa std::is_constructiblegerçekten tutarsız mı?


1
Bir GCC böcek gibi görünüyor, clang 9 baskılar00
Yksisarvinen

1
Makinemde c ++ 17 g ++ 9.2.1 / g ++ - 10.0 ile derlerken ve std :: is_constructible <...> :: değerini is_constructible_v <...> ile değiştirirken fark ettiğim bir başka garip düşünmek sonucu 00 olarak değiştirildi
mutableVoid

1
@mutableVoid Gerçekten - ve ::valuesürümün kendisinden önce gelenlerin çıktısını da değiştirebileceği anlaşılıyor : godbolt.org/z/zCy5xU Yorumlanan satırı açın ve hepsi gcc cinsinden 1: s olur.
Ted Lyngmo

1
Bunu düzeltmenin başka bir yolu: godbolt.org/z/EKaP3r Yani temelde bu bir tür değerlendirme sırası hatası.
Marek R

2
@mutableVoid İşlev şablonunun gerçek olması için başlatmanıza bile gerek yoktur. Bu örnekte geri döner, falseancak işlev şablonu önerilmezse , aniden döndürür true: godbolt.org/z/zqxdk2
Ted Lyngmo

Yanıtlar:


3

std::is_constructiblefalseyapıcı erişilebilir olmadığından bu senaryoda dönmelidir .

Sorunun altında belirtildiği gibi, soruda açıklanan davranışa GCC / libstdc ++ 'da bir hata neden olur. Hata burada bildirilir ve Bugzilla'ya göre , bir süredir çözülmemiş şablon fonksiyonlarındaki sınıflar için bir erişim kontrol hatasından kaynaklanmıyorsa ilgili . İki böcek arasındaki ilişki, Jonathan Wakely'nin önce iki böcek arasındaki bağlantıyı tespit etmiş gibi görünen Bugzilla yorumundan alınmıştır.

Bu, GCC'deki bu senaryonun davranışının, yapıcıyı silerken özel yapmak yerine silmesinin doğru hale gelmesiyle de ima edilir:

class Class {
    Class() = delete;
};

çıktılar 0ve 00sırasıyla. Bu doğru çıktıdır ( clangsenaryoda özel bir kurucu ile de doğru raporlar).

Bu , satırda yorum yaparken gözlenen davranış değişikliğini açıklayabilir , çünkü şablonlanmış yapıdaki işlev içinde erişim denetimi çalışmaz ve yapıcı olmadığında erişilebilir olduğunu bildirir. Özellik bir sonraki satırda veya muhtemelen tamamen farklı bir konumda ( burada olduğu gibi ) tekrar kontrol edildiğinde, zaten somutlaştırılmıştır ve böylece yanlış cevap verir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.