From ae5e97a00568d15dedea073b58668e646e3c0d2e Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Thu, 14 Feb 2019 17:29:57 +0100 Subject: [PATCH] Delete some default constructors and assignment operators They are unused, but if someone used them they would lead to problems since they would copy the internal raw pointers and the destructor would cause double delete --- Source/CPack/cmCPackGeneratorFactory.h | 3 +++ Source/CPack/cmCPackLog.h | 3 +++ Source/CTest/cmCTestBuildAndTestHandler.cxx | 5 +++++ Source/CTest/cmCTestBuildHandler.cxx | 2 ++ Source/CTest/cmCTestCoverageHandler.cxx | 5 +++++ Source/CTest/cmCTestCurl.h | 2 ++ Source/CTest/cmCTestHandlerCommand.cxx | 2 ++ Source/CTest/cmCTestLaunch.h | 3 +++ Source/cmArchiveWrite.cxx | 2 ++ Source/cmArchiveWrite.h | 3 +++ Source/cmCPluginAPI.cxx | 4 ++++ Source/cmCTest.h | 3 +++ Source/cmComputeLinkDepends.h | 3 +++ Source/cmCustomCommandGenerator.h | 3 +++ Source/cmDependsJavaParserHelper.h | 4 ++++ Source/cmELF.h | 3 +++ Source/cmExportSet.h | 3 +++ Source/cmExportSetMap.cxx | 2 ++ Source/cmExportSetMap.h | 5 +++++ Source/cmFileCommand.cxx | 3 +++ Source/cmFileTimeComparison.h | 3 +++ Source/cmFindPackageCommand.cxx | 3 +++ Source/cmFortranParser.h | 3 +++ Source/cmInstalledFile.h | 6 ++++++ Source/cmListFileCache.cxx | 2 ++ Source/cmMakefile.cxx | 12 ++++++++++++ Source/cmMakefile.h | 9 +++++++++ Source/cmOrderDirectories.h | 2 ++ Source/cmOutputRequiredFilesCommand.cxx | 3 +++ Source/cmSourceFile.h | 3 +++ Source/cmState.h | 3 +++ Source/cmSystemTools.cxx | 4 +++- Source/cmVariableWatch.h | 3 +++ Source/cmWorkingDirectory.h | 3 +++ Source/cmXMLWriter.h | 5 +++++ 35 files changed, 126 insertions(+), 1 deletion(-) diff --git a/Source/CPack/cmCPackGeneratorFactory.h b/Source/CPack/cmCPackGeneratorFactory.h index 7f633e4739..972f0f73cb 100644 --- a/Source/CPack/cmCPackGeneratorFactory.h +++ b/Source/CPack/cmCPackGeneratorFactory.h @@ -22,6 +22,9 @@ public: cmCPackGeneratorFactory(); ~cmCPackGeneratorFactory(); + cmCPackGeneratorFactory(const cmCPackGeneratorFactory&) = delete; + cmCPackGeneratorFactory& operator=(const cmCPackGeneratorFactory&) = delete; + //! Get the generator cmCPackGenerator* NewGenerator(const std::string& name); void DeleteGenerator(cmCPackGenerator* gen); diff --git a/Source/CPack/cmCPackLog.h b/Source/CPack/cmCPackLog.h index 8e99221219..65281e3d8b 100644 --- a/Source/CPack/cmCPackLog.h +++ b/Source/CPack/cmCPackLog.h @@ -26,6 +26,9 @@ public: cmCPackLog(); ~cmCPackLog(); + cmCPackLog(const cmCPackLog&) = delete; + cmCPackLog& operator=(const cmCPackLog&) = delete; + enum __log_tags { NOTAG = 0, diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index 696b52fa11..b2c88df6d1 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -140,6 +140,11 @@ public: cmSystemTools::SetStdoutCallback(nullptr); cmSystemTools::SetMessageCallback(nullptr); } + + cmCTestBuildAndTestCaptureRAII(const cmCTestBuildAndTestCaptureRAII&) = + delete; + cmCTestBuildAndTestCaptureRAII& operator=( + const cmCTestBuildAndTestCaptureRAII&) = delete; }; int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index af664bad24..c75f4d452d 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -680,6 +680,8 @@ class cmCTestBuildHandler::LaunchHelper public: LaunchHelper(cmCTestBuildHandler* handler); ~LaunchHelper(); + LaunchHelper(const LaunchHelper&) = delete; + LaunchHelper& operator=(const LaunchHelper&) = delete; private: cmCTestBuildHandler* Handler; diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 10928e0598..4dda9ad9bc 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -52,6 +52,8 @@ public: } cmsysProcess_Delete(this->Process); } + cmCTestRunProcess(const cmCTestRunProcess&) = delete; + cmCTestRunProcess& operator=(const cmCTestRunProcess&) = delete; void SetCommand(const char* command) { this->CommandLineStrings.clear(); @@ -786,6 +788,9 @@ struct cmCTestCoverageHandlerLocale cmSystemTools::UnsetEnv("LC_ALL"); } } + cmCTestCoverageHandlerLocale(const cmCTestCoverageHandlerLocale&) = delete; + cmCTestCoverageHandlerLocale& operator=( + const cmCTestCoverageHandlerLocale&) = delete; std::string lc_all; }; diff --git a/Source/CTest/cmCTestCurl.h b/Source/CTest/cmCTestCurl.h index 86d9489958..6186af8d20 100644 --- a/Source/CTest/cmCTestCurl.h +++ b/Source/CTest/cmCTestCurl.h @@ -16,6 +16,8 @@ class cmCTestCurl public: cmCTestCurl(cmCTest*); ~cmCTestCurl(); + cmCTestCurl(const cmCTestCurl&) = delete; + cmCTestCurl& operator=(const cmCTestCurl&) = delete; bool UploadFile(std::string const& local_file, std::string const& url, std::string const& fields, std::string& response); bool HttpRequest(std::string const& url, std::string const& fields, diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx index 57a14efd1b..adf955399f 100644 --- a/Source/CTest/cmCTestHandlerCommand.cxx +++ b/Source/CTest/cmCTestHandlerCommand.cxx @@ -76,6 +76,8 @@ public: } } } + SaveRestoreErrorState(const SaveRestoreErrorState&) = delete; + SaveRestoreErrorState& operator=(const SaveRestoreErrorState&) = delete; private: bool InitialErrorState; diff --git a/Source/CTest/cmCTestLaunch.h b/Source/CTest/cmCTestLaunch.h index debbe59d79..107fd61746 100644 --- a/Source/CTest/cmCTestLaunch.h +++ b/Source/CTest/cmCTestLaunch.h @@ -28,6 +28,9 @@ private: cmCTestLaunch(int argc, const char* const* argv); ~cmCTestLaunch(); + cmCTestLaunch(const cmCTestLaunch&) = delete; + cmCTestLaunch& operator=(const cmCTestLaunch&) = delete; + // Run the real command. int Run(); void RunChild(); diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index 6e5109aa1a..23be603f13 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -54,6 +54,8 @@ public: { } ~Entry() { archive_entry_free(this->Object); } + Entry(const Entry&) = delete; + Entry& operator=(const Entry&) = delete; operator struct archive_entry*() { return this->Object; } }; diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h index 6ecdd630c5..1f23daebc6 100644 --- a/Source/cmArchiveWrite.h +++ b/Source/cmArchiveWrite.h @@ -58,6 +58,9 @@ public: ~cmArchiveWrite(); + cmArchiveWrite(const cmArchiveWrite&) = delete; + cmArchiveWrite& operator=(const cmArchiveWrite&) = delete; + /** * Add a path (file or directory) to the archive. Directories are * added recursively. The "path" must be readable on disk, either diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index 576d2c37e1..5efc7842a8 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -491,12 +491,16 @@ public: typedef std::map derived; typedef derived::iterator iterator; typedef derived::value_type value_type; + cmCPluginAPISourceFileMap() = default; ~cmCPluginAPISourceFileMap() { for (auto const& i : *this) { delete i.second; } } + cmCPluginAPISourceFileMap(const cmCPluginAPISourceFileMap&) = delete; + cmCPluginAPISourceFileMap& operator=(const cmCPluginAPISourceFileMap&) = + delete; }; cmCPluginAPISourceFileMap cmCPluginAPISourceFiles; diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 92a02c3169..7dbf4d536a 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -182,6 +182,9 @@ public: cmCTest(); ~cmCTest(); + cmCTest(const cmCTest&) = delete; + cmCTest& operator=(const cmCTest&) = delete; + /** Set the notes files to be created. */ void SetNotesFiles(const char* notes); diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index 252f8748ce..dfaaf8b968 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -31,6 +31,9 @@ public: const std::string& config); ~cmComputeLinkDepends(); + cmComputeLinkDepends(const cmComputeLinkDepends&) = delete; + cmComputeLinkDepends& operator=(const cmComputeLinkDepends&) = delete; + // Basic information about each link item. struct LinkEntry { diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h index 9684cffa87..7fd60c0c4f 100644 --- a/Source/cmCustomCommandGenerator.h +++ b/Source/cmCustomCommandGenerator.h @@ -32,6 +32,9 @@ public: cmCustomCommandGenerator(cmCustomCommand const& cc, std::string config, cmLocalGenerator* lg); ~cmCustomCommandGenerator(); + cmCustomCommandGenerator(const cmCustomCommandGenerator&) = delete; + cmCustomCommandGenerator& operator=(const cmCustomCommandGenerator&) = + delete; cmCustomCommand const& GetCC() const { return this->CC; } unsigned int GetNumberOfCommands() const; std::string GetCommand(unsigned int c) const; diff --git a/Source/cmDependsJavaParserHelper.h b/Source/cmDependsJavaParserHelper.h index 0b445d9244..a673b5bbbb 100644 --- a/Source/cmDependsJavaParserHelper.h +++ b/Source/cmDependsJavaParserHelper.h @@ -24,6 +24,10 @@ public: cmDependsJavaParserHelper(); ~cmDependsJavaParserHelper(); + cmDependsJavaParserHelper(const cmDependsJavaParserHelper&) = delete; + cmDependsJavaParserHelper& operator=(const cmDependsJavaParserHelper&) = + delete; + int ParseString(const char* str, int verb); int ParseFile(const char* file); diff --git a/Source/cmELF.h b/Source/cmELF.h index c8a91e4eaa..987f0c3a48 100644 --- a/Source/cmELF.h +++ b/Source/cmELF.h @@ -28,6 +28,9 @@ public: /** Destruct. */ ~cmELF(); + cmELF(const cmELF&) = delete; + cmELF& operator=(const cmELF&) = delete; + /** Get the error message if any. */ std::string const& GetErrorMessage() const { return this->ErrorMessage; } diff --git a/Source/cmExportSet.h b/Source/cmExportSet.h index 0ef306f639..d654c12858 100644 --- a/Source/cmExportSet.h +++ b/Source/cmExportSet.h @@ -25,6 +25,9 @@ public: /// Destructor ~cmExportSet(); + cmExportSet(const cmExportSet&) = delete; + cmExportSet& operator=(const cmExportSet&) = delete; + void Compute(cmLocalGenerator* lg); void AddTargetExport(cmTargetExport* tgt); diff --git a/Source/cmExportSetMap.cxx b/Source/cmExportSetMap.cxx index 0740828358..293e80cf91 100644 --- a/Source/cmExportSetMap.cxx +++ b/Source/cmExportSetMap.cxx @@ -23,6 +23,8 @@ void cmExportSetMap::clear() this->derived::clear(); } +cmExportSetMap::cmExportSetMap() = default; + cmExportSetMap::~cmExportSetMap() { this->clear(); diff --git a/Source/cmExportSetMap.h b/Source/cmExportSetMap.h index 0f71c790c9..385373240a 100644 --- a/Source/cmExportSetMap.h +++ b/Source/cmExportSetMap.h @@ -25,8 +25,13 @@ public: void clear(); + cmExportSetMap(); + /// Overloaded destructor deletes all member export sets. ~cmExportSetMap(); + + cmExportSetMap(const cmExportSetMap&) = delete; + cmExportSetMap& operator=(const cmExportSetMap&) = delete; }; #endif diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index aa75a8cc8c..12f1cbb5a7 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2691,6 +2691,9 @@ public: } } + cURLEasyGuard(const cURLEasyGuard&) = delete; + cURLEasyGuard& operator=(const cURLEasyGuard&) = delete; + void release() { this->Easy = nullptr; } private: diff --git a/Source/cmFileTimeComparison.h b/Source/cmFileTimeComparison.h index 5f74e34990..b4e4eb3c14 100644 --- a/Source/cmFileTimeComparison.h +++ b/Source/cmFileTimeComparison.h @@ -20,6 +20,9 @@ public: cmFileTimeComparison(); ~cmFileTimeComparison(); + cmFileTimeComparison(const cmFileTimeComparison&) = delete; + cmFileTimeComparison& operator=(const cmFileTimeComparison&) = delete; + /** * Compare file modification times. * Return true for successful comparison and false for error. diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 45b096fe8d..0d22ed8e77 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -1372,6 +1372,9 @@ public: cmSystemTools::RemoveFile(this->File); } } + cmFindPackageCommandHoldFile(const cmFindPackageCommandHoldFile&) = delete; + cmFindPackageCommandHoldFile& operator=( + const cmFindPackageCommandHoldFile&) = delete; void Release() { this->File = nullptr; } }; diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h index 076234035b..6a33be571a 100644 --- a/Source/cmFortranParser.h +++ b/Source/cmFortranParser.h @@ -141,6 +141,9 @@ struct cmFortranParser_s std::set defines, cmFortranSourceInfo& info); ~cmFortranParser_s(); + cmFortranParser_s(const cmFortranParser_s&) = delete; + cmFortranParser_s& operator=(const cmFortranParser_s&) = delete; + bool FindIncludeFile(const char* dir, const char* includeName, std::string& fileName); diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h index 070b954e67..b7d602ef42 100644 --- a/Source/cmInstalledFile.h +++ b/Source/cmInstalledFile.h @@ -32,6 +32,9 @@ public: Property(); ~Property(); + Property(const Property&) = delete; + Property& operator=(const Property&) = delete; + ExpressionVectorType ValueExpressions; }; @@ -41,6 +44,9 @@ public: ~cmInstalledFile(); + cmInstalledFile(const cmInstalledFile&) = delete; + cmInstalledFile& operator=(const cmInstalledFile&) = delete; + void RemoveProperty(const std::string& prop); void SetProperty(cmMakefile const* mf, const std::string& prop, diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index f85511964a..f99caed69b 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -27,6 +27,8 @@ struct cmListFileParser cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt, cmMessenger* messenger, const char* filename); ~cmListFileParser(); + cmListFileParser(const cmListFileParser&) = delete; + cmListFileParser& operator=(const cmListFileParser&) = delete; void IssueFileOpenError(std::string const& text) const; void IssueError(std::string const& text) const; bool ParseFile(); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index b0dacf1024..560181f7a2 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -348,6 +348,9 @@ public: this->Makefile->Backtrace = this->Makefile->Backtrace.Pop(); } + cmMakefileCall(const cmMakefileCall&) = delete; + cmMakefileCall& operator=(const cmMakefileCall&) = delete; + private: cmMakefile* Makefile; }; @@ -439,6 +442,9 @@ public: ~IncludeScope(); void Quiet() { this->ReportError = false; } + IncludeScope(const IncludeScope&) = delete; + IncludeScope& operator=(const IncludeScope&) = delete; + private: cmMakefile* Makefile; bool NoPolicyScope; @@ -606,6 +612,9 @@ public: void Quiet() { this->ReportError = false; } + ListFileScope(const ListFileScope&) = delete; + ListFileScope& operator=(const ListFileScope&) = delete; + private: cmMakefile* Makefile; bool ReportError; @@ -1497,6 +1506,9 @@ public: void Quiet() { this->ReportError = false; } + BuildsystemFileScope(const BuildsystemFileScope&) = delete; + BuildsystemFileScope& operator=(const BuildsystemFileScope&) = delete; + private: cmMakefile* Makefile; cmGlobalGenerator* GG; diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 9f019862c2..0800ce4b40 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -313,6 +313,9 @@ public: PolicyPushPop(cmMakefile* m); ~PolicyPushPop(); + PolicyPushPop(const PolicyPushPop&) = delete; + PolicyPushPop& operator=(const PolicyPushPop&) = delete; + private: cmMakefile* Makefile; }; @@ -743,6 +746,9 @@ public: cmPolicies::PolicyMap const& pm); ~FunctionPushPop(); + FunctionPushPop(const FunctionPushPop&) = delete; + FunctionPushPop& operator=(const FunctionPushPop&) = delete; + void Quiet() { this->ReportError = false; } private: @@ -757,6 +763,9 @@ public: cmPolicies::PolicyMap const& pm); ~MacroPushPop(); + MacroPushPop(const MacroPushPop&) = delete; + MacroPushPop& operator=(const MacroPushPop&) = delete; + void Quiet() { this->ReportError = false; } private: diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h index 5916f7ab4f..23e61d678a 100644 --- a/Source/cmOrderDirectories.h +++ b/Source/cmOrderDirectories.h @@ -25,6 +25,8 @@ public: cmOrderDirectories(cmGlobalGenerator* gg, cmGeneratorTarget const* target, const char* purpose); ~cmOrderDirectories(); + cmOrderDirectories(const cmOrderDirectories&) = delete; + cmOrderDirectories& operator=(const cmOrderDirectories&) = delete; void AddRuntimeLibrary(std::string const& fullPath, const char* soname = nullptr); void AddLinkLibrary(std::string const& fullPath); diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index 46d04a65f0..e0c1dad523 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -92,6 +92,9 @@ public: */ ~cmLBDepend() { cmDeleteAll(this->DependInformationMap); } + cmLBDepend(const cmLBDepend&) = delete; + cmLBDepend& operator=(const cmLBDepend&) = delete; + /** * Set the makefile that is used as a source of classes. */ diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index a82a58aa90..d579018948 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -34,6 +34,9 @@ public: ~cmSourceFile(); + cmSourceFile(const cmSourceFile&) = delete; + cmSourceFile& operator=(const cmSourceFile&) = delete; + /** * Get the list of the custom commands for this source file */ diff --git a/Source/cmState.h b/Source/cmState.h index f755f8362d..190eafcb1c 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -35,6 +35,9 @@ public: cmState(); ~cmState(); + cmState(const cmState&) = delete; + cmState& operator=(const cmState&) = delete; + enum Mode { Unknown, diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index a5d191d3f2..276cb57f2e 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -521,6 +521,8 @@ public: } free(this->ArgV); } + cmSystemToolsArgV(const cmSystemToolsArgV&) = delete; + cmSystemToolsArgV& operator=(const cmSystemToolsArgV&) = delete; void Store(std::vector& args) const { for (char** arg = this->ArgV; arg && *arg; ++arg) { @@ -533,7 +535,7 @@ void cmSystemTools::ParseUnixCommandLine(const char* command, std::vector& args) { // Invoke the underlying parser. - cmSystemToolsArgV argv = cmsysSystem_Parse_CommandForUnix(command, 0); + cmSystemToolsArgV argv(cmsysSystem_Parse_CommandForUnix(command, 0)); argv.Store(args); } diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h index 5855fed292..1230101797 100644 --- a/Source/cmVariableWatch.h +++ b/Source/cmVariableWatch.h @@ -72,6 +72,9 @@ protected: this->DeleteDataCall(this->ClientData); } } + Pair() = default; + Pair(const Pair&) = delete; + Pair& operator=(const Pair&) = delete; }; typedef std::vector> VectorOfPairs; diff --git a/Source/cmWorkingDirectory.h b/Source/cmWorkingDirectory.h index 1f18ce7a37..d4a164de62 100644 --- a/Source/cmWorkingDirectory.h +++ b/Source/cmWorkingDirectory.h @@ -22,6 +22,9 @@ public: cmWorkingDirectory(std::string const& newdir); ~cmWorkingDirectory(); + cmWorkingDirectory(const cmWorkingDirectory&) = delete; + cmWorkingDirectory& operator=(const cmWorkingDirectory&) = delete; + bool SetDirectory(std::string const& newdir); void Pop(); bool Failed() const { return ResultCode != 0; } diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h index 1df8a09d77..512e1031dc 100644 --- a/Source/cmXMLWriter.h +++ b/Source/cmXMLWriter.h @@ -146,6 +146,8 @@ public: xmlwr.StartDocument(); } ~cmXMLDocument() { xmlwr.EndDocument(); } + cmXMLDocument(const cmXMLDocument&) = delete; + cmXMLDocument& operator=(const cmXMLDocument&) = delete; private: friend class cmXMLElement; @@ -172,6 +174,9 @@ public: } ~cmXMLElement() { xmlwr.EndElement(); } + cmXMLElement(const cmXMLElement&) = delete; + cmXMLElement& operator=(const cmXMLElement&) = delete; + template cmXMLElement& Attribute(const char* name, T const& value) {