如何定义is_instantiable类型特征?

时间:2018-04-08 08:12:41

标签: c++ instance language-lawyer template-meta-programming typetraits

让我们考虑以下形式的类型特征:

import java.awt.*;
import javax.swing.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; 

public class App1 extends JFrame implements ActionListener
    {
            JPanel upperBase, lowerBase, jpRed, jpGreen, jpBlue, jpChanging;
            JLabel jLRed, jLGreen, jLBlue;
            JTextField jtf_red, jtf_green, jtf_blue;
            JButton rP, rM, gP, gM, bP, bM;

        public static void main(String[] args) 
    {
        App1 app = new App1();
    } 

    App1()
{
    // Creates Container
    // Sets Layout for Container
    Container cp = this.getContentPane();
    cp.setLayout(new BoxLayout (cp, BoxLayout.Y_AXIS));

     // Sets Window Title and Size
     // Exits Application on Close
    this.setTitle("Application 1");
    this.setSize(800, 600);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // Creates 6 JPanels
    upperBase = new JPanel();
    lowerBase = new JPanel();
    jpRed = new JPanel();
    jpGreen = new JPanel();
    jpBlue = new JPanel();
    jpChanging =  new JPanel();

    // Adds upper/lowerBase to Container
    cp.add(upperBase);
    cp.add(lowerBase);

    // Sets Layout for upper/lowerBase
    upperBase.setLayout(new GridLayout(1,3));
    lowerBase.setLayout(new GridLayout(1,1));

    // Sets Color for jpRed/Green/Blue
    jpRed.setBackground(Color.RED);
    jpGreen.setBackground(Color.GREEN);
    jpBlue.setBackground(Color.BLUE);
    jpChanging.setBackground(Color.BLACK);

    // Adds jpRed/Green/Blue to upperBase & adds jpChanging to lowerBase
    upperBase.add(jpRed);
    upperBase.add(jpGreen);
    upperBase.add(jpBlue);
    lowerBase.add(jpChanging);

    // Setup for Red JPanel (jpRed)
    jLRed = new JLabel("Red");
    jtf_red = new JTextField("0", 10);

    rP = new JButton("+");
    rM = new JButton("-");
    rP.addActionListener(this);
    rM.addActionListener(this);
    rP.setPreferredSize(new Dimension(25, 25));
    rM.setPreferredSize(new Dimension(25, 25));

    jpRed.add(jLRed);
    jpRed.add(rP);
    jpRed.add(jtf_red);
    jpRed.add(rM);


    // Setup for Green JPanel (jpGreen)
    jLGreen = new JLabel("Green");
    jtf_green = new JTextField("0", 10);

    gP = new JButton("+");
    gM = new JButton("-");
    gP.addActionListener(this);
    gM.addActionListener(this);
    gP.setPreferredSize(new Dimension(25, 25));
    gM.setPreferredSize(new Dimension(25, 25));

    jpGreen.add(jLGreen);
    jpGreen.add(gP);
    jpGreen.add(jtf_green);
    jpGreen.add(gM);

    // Setup for Blue JPanel (jpBlue)
    jLBlue = new JLabel("Blue");
    jtf_blue = new JTextField("0", 10);

    bP = new JButton("+");
    bM = new JButton("-");
    bP.addActionListener(this);
    bM.addActionListener(this);
    bP.setPreferredSize(new Dimension(25, 25));
    bM.setPreferredSize(new Dimension(25, 25));

    jpBlue.add(jLBlue);
    jpBlue.add(bP);
    jpBlue.add(jtf_blue);
    jpBlue.add(bM);

    // Visibility
    this.setVisible(true);
}

public void actionPerformed(ActionEvent e) {
    int red = Integer.parseInt(jtf_red.getText());
    int green = Integer.parseInt(jtf_green.getText());
    int blue = Integer.parseInt(jtf_blue.getText());

    // PLUS & MINUS, NO DECREMENTS PAST 0 and INCREMENTS PAST 255
    if(e.getSource() == rP)
    {
        red++;
        jtf_red.setText("" + red);

        if (red > 255)
        {
            jtf_red.setText("" + 255);
        }
    }
    else if(e.getSource()  == rM)
    {
        red--;
        jtf_red.setText("" + red);

        if (red < 0)
        {
            jtf_red.setText("" + 0);

        }
    }

    if(e.getSource() == gP)
    {
        green++;
        jtf_green.setText("" + green);

        if (green > 255)
        {
            jtf_green.setText("" + 255);
        }
    }
    else if(e.getSource()  == gM)
    {
        green--;
        jtf_green.setText("" + green);

        if (green < 0)
        {
            jtf_green.setText("" + 0);
        }
    }

    if(e.getSource() == bP)
    {
        blue++;
        jtf_blue.setText("" + blue);

        if (blue > 255)
        {
            jtf_blue.setText("" + 255);
        }
    }
    else if(e.getSource()  == bM)
    {
        blue--;
        jtf_blue.setText("" + blue);

        if (blue < 0)
        {
            jtf_blue.setText("" + 0);
        }
    }       

    // LIMITS (0-255)
    if (red < 0)
    {
        jtf_red.setText("" + 0);
    }
    else if (red > 255)
    {
        jtf_red.setText("" + 255);
    }

    if (green < 0)
    {
        jtf_green.setText("" + 0);
    }
    else if (green > 255)
    {
        jtf_green.setText("" + 255);
    }

    if (blue < 0)
    {
        jtf_blue.setText("" + 0);
    }
    else if (blue > 255)
    {
         jtf_blue.setText("" + 255);
    }

    jpChanging.setBackground(new Color(red, green, blue));
}

将检测是否可以实例化template <class T> struct is_instantiable { static constexpr bool value = /* something */; }; template <class T> inline constexpr bool is_instantiable_v = is_instantiable<T>::value; 类型的实体。

目前,标准库已经具有T等特征(但它需要构造对象的参数)。我在想:

  • is_constructible类型特征是否有用?
  • 是否允许使用is_instantiable
  • 目前存在问题的内容
  • 如何定义/实现它(如果需要一些编译器魔法,它还可以吗?)

目前我不知道这样的东西是否会有用吗? (如果您在is_constructible限制时有任何有趣的用例,那就太棒了。)

1 个答案:

答案 0 :(得分:1)

让我们反过来思考一下。 我假设通过无法实例化的东西,你的意思是没有一个有效的构造函数并且不是内置类型。 据我所知,你可以通过强制转换(使用reinterpret_cast?)来提供任何类型的唯一方法,一个无法构造的实例。 在我看来,编写这样的代码是一个可怕的决定,但我认为它理论上可以发生。

我想,一个用例就是你希望你正在处理的对象可能是由这样的演员制作的,你想知道是否属于这种情况。

询问编译器肯定是一个深奥的问题,我不知道如何有效地使用这些信息,也不知道如何实现这一特性。