【问题标题】:c++11: delegate constructor - can't select constructor template?c++11:委托构造函数 - 不能选择构造函数模板?
【发布时间】:2020-09-02 04:23:18
【问题描述】:

这是一个后续问题:
c++11 dedicated "proxy constructors" delegating to private univeral reference constructor?

我想摆脱那里使用的“枚举类 Dummy”。

但我无法委托给模板构造函数。
请参阅下面的代码示例。

#include <iostream>
#include <string>
#include <typeinfo>

class MyClass
{

private:

    template <class T>
    MyClass(T&& data)
    : _data(std::forward<T>(data))
    {
        std::cout << "MyClass universal reference template c'tor" << std::endl;
    }

public:


    // proxy c'tors delegating to universal reference c'tor
    MyClass (std::string const & data)
    : MyClass<std::string>(data)
    {
        std::cout << "MyClass lvalue c'tor" << std::endl;
    }

    MyClass (std::string && data)
    : MyClass<std::string>(std::move(data))
    {
        std::cout << "MyClass rvalue c'tor" << std::endl;
    }

private:

    std::string _data;

};

int
main(
        int,
        char**)
{

    {
        std::string str("demo");
        MyClass myClass(str);
    }

    {
        MyClass myClass("hello, world");
    }

    return 0;
}

我收到以下错误:

main2.cpp: In constructor 'MyClass::MyClass(const string&)':
main2.cpp:21:7: error: 'class MyClass MyClass::MyClass' is not a non-static data member of 'MyClass'
 : MyClass<std::string>(data)
   ^
main2.cpp:21:14: error: expected '(' before '<' token
 : MyClass<std::string>(data)
          ^
main2.cpp:21:14: error: expected '{' before '<' token
main2.cpp: In constructor 'MyClass::MyClass(std::__cxx11::string&&)':
main2.cpp:27:7: error: 'class MyClass MyClass::MyClass' is not a non-static data member of 'MyClass'
 : MyClass<std::string>(std::move(data))
   ^
main2.cpp:27:14: error: expected '(' before '<' token
 : MyClass<std::string>(std::move(data))
          ^
main2.cpp:27:14: error: expected '{' before '<' token
main2.cpp: In function 'int main(int, char**)':
main2.cpp:11:5: error: 'MyClass::MyClass(T&&) [with T = std::__cxx11::basic_string<char>&]' is private
 MyClass(T&& data)
 ^
main2.cpp:46:28: error: within this context
     MyClass myClass(str);
                        ^
main2.cpp:11:5: error: 'MyClass::MyClass(T&&) [with T = const char (&)[13]]' is private
 MyClass(T&& data)
 ^
main2.cpp:50:39: error: within this context
     MyClass myClass("hello, world");

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    这并不特定于委托构造函数。构造函数(和转换函数)没有名称,因此语言中无法为它们提供显式模板参数。引用 C++14,[temp.mem] 14.5.2/5:

    [ 注意: 因为显式模板参数列表遵循函数模板名称, 并且因为调用了转换成员函数模板和构造函数成员函数模板 如果不使用函数名,就无法为这些提供显式模板参数列表 功能模板。 ——尾注 ]

    注释不是规范性的,但该注释只是明确说明了第 14 章中的规则。

    【讨论】:

      【解决方案2】:

      Scott Mayers 无疑是 C++ 专家,但他并不总是正确。

      问题:

      允许尽可能高效的构造,尽可能限制副本

      答案:

      X 值构造函数,受 std::enable_if: 限制

      #include <iostream>
      #include <string>
      #include <type_traits>
      
      class MyClass
      {
      
      public:
      
          template <class T, std::enable_if_t<std::is_constructible<std::string, T>::value>* = nullptr>
          MyClass(T&& data)
          : _data(std::forward<T>(data))
          {
              std::cout << "MyClass universal reference template c'tor" << std::endl;
          }
      
      private:
      
          std::string _data;
      
      };
      
      int main()
      {
          using namespace std::string_literals;
      
          auto a = MyClass("hello"s);
          auto b = MyClass("world");
      
      
          const auto s = "Hello, World"s;
          auto s2 = "Hello, World";
      
          auto c = MyClass(s);
          auto d = MyClass(s2);
      
      // won't compile
      //    auto e = MyClass(10);
      
      }
      

      【讨论】:

      • 我的错:Scott Meyer 正在处理第 27 项中的问题
      • 嗯,不完全是这样。但是对于类似的情况,使用 SFINAE 进行模板元编程。您的示例帮助我更好地理解 - 非常感谢!
      猜你喜欢
      • 2015-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-21
      • 1970-01-01
      相关资源
      最近更新 更多